1

I have AudioBuffer as shown below. It can play through the speaker. I would like to know a way to amplify those buffer before I play. How shall I modify?

/**
 This callback is called when the audioUnit needs new data to play through the
 speakers. If you don't have any, just don't write anything in the buffers
*/
static OSStatus playbackCallback(void *inRefCon, 
                             AudioUnitRenderActionFlags *ioActionFlags, 
                             const AudioTimeStamp *inTimeStamp, 
                             UInt32 inBusNumber, 
                             UInt32 inNumberFrames, 
                             AudioBufferList *ioData) {    
// Notes: ioData contains buffers (may be more than one!)
// Fill them up as much as you can. Remember to set the size value in each buffer to match how
// much data is in the buffer.


for (int i=0; i < ioData->mNumberBuffers; i++) { // in practice we will only ever have 1 buffer, since audio format is mono




    AudioBuffer buffer = ioData->mBuffers[i];


  //        NSLog(@"  Buffer %d has %d channels and wants %d bytes of data.", i, buffer.mNumberChannels, buffer.mDataByteSize);

    // copy temporary buffer data to output buffer
    UInt32 size = min(buffer.mDataByteSize, [iosAudio tempBuffer].mDataByteSize); // dont copy more data then we have, or then fits
    memcpy(buffer.mData, [iosAudio tempBuffer].mData, size);
    buffer.mDataByteSize = size; // indicate how much data we wrote in the buffer

    // uncomment to hear random noise
    /*
    UInt16 *frameBuffer = buffer.mData;
    for (int j = 0; j < inNumberFrames; j++) {
        frameBuffer[j] = rand();
    }
    */

}

return noErr;
}
Khant Thu Linn
  • 5,905
  • 7
  • 52
  • 120
  • multiply each value in the buffer by a value greater than one like 1.5. Consider adding a limiter if you do this. – meggar Jan 23 '14 at 14:11
  • if possible, can you write detail? I don't really know where to change. – Khant Thu Linn Jan 24 '14 at 15:28
  • 1
    for example, you already have `frameBuffer[j] = rand();` to replace each sample with a random value. similarly, you could use `frameBuffer[j] *= 2;` to double the amplitude. The reason to add a limiter function if you do this is that the new value might be larger than the max value of UInt16. – meggar Jan 24 '14 at 20:44
  • Thanks meggar. It help me. I think audio is also distorted. If possible, can you advise me how to do? – Khant Thu Linn Jan 25 '14 at 08:51
  • Don't use unsigned integer. Multiply negative and positive values by the amplitude level. Choose a value above which to attenuate, for example 20000, so if abs(frameBuffer[j] * amplitude_level) > 20000 then apply a function that assures that the value does not exceed the bounds of int16 while keeping the waveform the same as much as possible. – meggar Jan 25 '14 at 13:59
  • Shall I use UInt32 or int32_t? If not, what shall I use? I don't know the maximum limit that I can amplify. – Khant Thu Linn Jan 31 '14 at 11:44
  • use int32_t to store the product, but then you need to adjust the product so that the maximum possible value is in the range -32,768 to 32,767, then convert back to int16_t. The only values that need to be adjusted are the ones that are over a certain threshold chosen by you, like 25000. Anything outside the range -25000 to 25000 you squash down until it fits into -32,768 to 32,767. For example, a sample of 30000 amplified by 2 = 60000, attenuated that could be (25000 + ((30000/32767) * (32767-25000))) = 32111. – meggar Jan 31 '14 at 23:59

0 Answers0