We have the Bitmap + BitmapExpression components for procedural textures, the Mesh + MeshExpression components for procedural geometry .. why not have Sample + SampleExpression components for procedural sounds?
Just like Meshes and Bitmaps not intended for real-time refresh, it would give you the possibility to generate more complex sounds ( and opens the possibility for cpu-intensive effect components ).
Another benefit of splitting the Sample property off from the Sound component is being able to use the same Sample with a number of Sound "presets" ( just like how you can re-use Bitmaps over multiple Materials ).
Interesting idea. The very first sound implementation in ZGE (before the first beta) used non-real time audio that worked similar to what you describe. A Sound-component had Producers that could be expressions and waveforms that were combined to a sample. Then I abandoned that when I wrote the real-time audio synth.
Today you can import a sample into the Sound-component directly. If we split it like you suggest it could be like this:
Sample "Sample1"
Producers
--SampleFromFile (import a sample from file)
--SampleExpression (run a expression over the audio)
Sound "Sound1" Sample="Sample1"
Sound "Sound2" Sample="Sample1"
(several sound instances with the same sample using different filter settings etc)
The only downside to this is that it is difficult to write expressions that produce interesting sounds and it require lots of effort and special knowledge that is not likely to be used by many. But if it can be implemented in a simple way it could be a powerful feature for those brave enough to use it.
The very first sound implementation in ZGE used non-real time audio.
Do you happen to have a build of this version lying around? Wouldn't mind giving it a spin ( even though the Expression compiler is probably ancient ).
Out of curiosity, did it require you to use a SampleFromFile to start with, or could you set the length / rate of the sample on the component itself ( cutting off a SampleFromFile when the imported data is longer / leaving a blank when it's shorter )?
I like this idea as it expands the procedural nature of ZGE to include sound samples,. of course the realtime sounds are procedural too, but this just opens up more areas to experimentation. The added bonus of being able to re-use samples and generated sounds in multiple zge realtime sounds is quite usefull as well,.
I looked for a pre-beta binaries but they are not on my computer, I can probably dig them up from my old computer but first I'll look if it can be implemented in the latest beta instead because that could be less work
The old implementation did not have the FromFile-component, instead there were SoundWaveform and SoundExpressions I think, and a length-property on the Sound-component to control the length of the sound.
Instead of Sound directly holding a imported sample it now references a new Sample-component that can be built up using producers similar to other procedural content.
New components:
Sample - Main content for procedural sound SampleImport - Producer that imports a sound from raw audio. SampleExpression - Producer that can generate or modify a sample.
New properties:
Sound.UseSampleHz - Check this box to playback sample in its original speed (without having to find the correct notenr).
When you open an old zgeproj-file that was created using samples ZGE will automatically convert it to the new format with separate Sample-components.
Only played around with it for a few minutes, but already loving it. Fantastic stuff ~
First bug (?) I noticed was that sounds seem to be played back at "rounded" rates? When testing the Tetris pattern some notes got rounded off to the same frequency while being different notes.
Yeah, I did notice there is something wrong with the playback quality sometimes and I tried to solve it but could not quite narrow it down. Can you produce an example that pinpoints the problem?
Sure, try previewing the Sound Component of the attached example in 6th Octave. ASD, FGHJ and KL produce identical sounds, while they should all differ in frequency obviously.
A recording of some quick & dirty samples created using expressions ( no modulators / filters used ) + another of a basic FM implementation. Will try to create some more complex sounds later.
That's great Kjell, if you want you can post expressions here for some basic instruments that can be included in the library! And do you have any links to websites with info on how to write sounds? MusicDSP still seems to be a good place.
I haven't made it clear in my post above but the benefit of generating samples off-line (instead of realtime) is that any complex expression can be evaluated that would be to slow for realtime use. You can use a mixture of sinewaves and even noise-functions etc to get rich sounds. The sound is generated when the application initializes (just like bitmaps and meshes) and can then be played back in realtime with different pitches, filter, modulations etc using the realtime synth and mixer.
Thanks for the link, as I've been mainly using Google + Wikipedia so far ~
Question: Because sound playback is controlled on a per-frame base, a sound stops playing at the first frame after its duration ( causing it to play a bit of the sample beginning, which is noticeable when you don't have Envelopes that pushed the volume all the way down at the end ). Can this be solved somehow?
Sounds are initiated on a per-frame basis and are triggered in the same frame as the PlaySound component is executed. After that they are controlled by the audio thread and live there own life outside frame timing. That's the way it's supposed to work anyway but since you are encountering problems maybe there is a bug. Do you use SampleRepeatPosition -1 to prevent looping? Any sudden drop/raise from or to zero in the sample will cause an audible click.