Consider that I have 100 instances of a “squeaker” class. Each “squeaker” object is capable of individually emitting a squeak sound. Each squeaker entity uses the same .mp3 resource. When all the squeakers are presented together on screen (for example as little characters), I want them all to squeak at approximately (but not exactly) the same time so that their combined squeaks are heard together as a crowd of squeakers.
Targeting iOS, what approach (and audio/sound framework) do you recommend? Has anyone done this before? Code samples?
It might be best to build this like a “laugh track”, where you use an audio editor to combine multiple squeaks into one MP3 file, which you then play in a loop (this file could and should be much longer than a single squeak).
By trying to render 100 sounds as separate sound-playing instances of whatever, you’d be running into the same sort of voice and latency problems encountered by developers of software synthesizers. Maintaining a voice count of 100 with an overall latency of less than 25 milliseconds or so is difficult to do on a modern PC, and much more difficult (or impossible) to do on an iPhone/iPad.
Generally speaking, voice and latency represent a fundamental engineering tradeoff: it’s fairly easy to have a low-latency synthesis engine on a mobile device, but this can only be achieved with a very small number of voices (i.e. distinct concurrent sounds). Conversely (like my own software synthesis engine), you can have an engine that can handle an effectively infinite number of voices, but with a very high latency (on the order of many seconds).
Update: generating your own sounds programmatically is an excellent idea. You can do this relatively easily in iPhone using the
AVAudioPlayerclass. Normally, this class is initialized using itsinitWithURLmethod, which is used to load audio data from a file.In your case, you want to instead use the
initWithDatamethod. You pass anNSDataobject here, which is basically just a block of bytes. In this case, you want the block of bytes to be an in-memory WAV file, which will consist of a 44-byte header followed by an array of 2-byte integers, which represents the actual sample data.You set the values in the header (stuff like sample rate, bits per sample, number of channels etc.) and then calculate the sample values using whatever algorithm you like. A simple
sinwave is a good thing to start with, but this will just produce a boring tone. A more interesting sound (and one that might be close to what you’re looking for) is called a “chirp” – this is basically a short sin-wave-based sound, but the frequency of the sin wave changes from high frequency to low frequency during the sound’s playback.Sorry, I have tons of audio code for C# and Java, but nothing yet for the iPhone. Hopefully what I’ve added here will help you google for this. You basically just need to figure out two things: 1) how to use
AVAudioPlayerusinginitWithData, and the file format of a WAV file.