views:

531

answers:

3

Hi,

I'm using Aran Mulhollan' RemoteIOPlayer, using audioqueues in the SDK iphone. I can without problems: - adding two signals to mix sounds - increasing sound volume by multiplying the UInt32 I get from the wav files

BUT every other operation gives me warped and distorted sound, and in particular I can't divide the signal. I can't seem to figure out what I'm doing wrong, the actual result of the division seems fine; some aspect of sound / signal processing must obviously be eluding me :)

Any help appreciated !

+1  A: 

Have you tried something like this?

- (void)setQueue:(AudioQueueRef)ref toVolume:(float)newValue {
  OSStatus rc = AudioQueueSetParameter(ref, kAudioQueueParam_Volume, newValue);
  if (rc) {
    NSLog(@"AudioQueueSetParameter returned %d when setting the volume.\n", rc);
  }
}
Frank Shearar
A: 

The iPhone handles audio as 16-bit integer. Most audio files are already normalized so that the peak sample values are the maximum that fit in a 16-bit signed integer. That means if you add two such samples together, you get overflow, or in this case, audio clipping. If you want to mix two audio sources together and ensure there's no clipping, you must average the samples: add them together and divide by two. Or you set the volume to half. If you're using decibels, that would be about a -6 dB change.

lucius
halving the volume is a nasty tradeoff, IMO. You can get away with it when mixing two channels -- but as you mix more and more, your channels get quieter and quieter.It's better (IMO) to mix your samples into a sint32_t and clamp the values to the sint16_t range. The resulting clipping doesn't occur as often as you might imagine it to since most samples aren't at the extremes, and you end up with all of the channels at full volume.
Dennis Munsie
In addition to mixing samples in 32-bit integer, you could also implement a dynamics compressor that behaves like a limiter with an instant attack and a fairly short (10 millisecond) release. It could be implemented as an IIR (infinite input response) filter, with a variable representing the volume that is reduced to prevent clipping and then slowly raised back to the original volume with each successive sample.
lucius
+1  A: 

First of all the code you mention does not use AudioQueues, it uses AudioUnits. The best way to mix audio in the iphone is using the mixer units that are inbuilt, there is some code on the site you downloaded your original example from here. Other than that what i would check in your code os that you have the correct data type. Are you trying your operations on Unsigned ints when you should be using signed ones? often that produces warped results (understandably)

Aran Mulholland