2

I am mixing two 16bit PCM samples into a short buffer.

// This is our buffer for PCM audio data
mp3Buffer = new short[minBufferSize];
wavBuffer = new short[minBufferSize];
mixedBuffer = new short[minBufferSize];

I am filling these buffers with samples from both the mp3 and wav files. I found out that the wav file will always be in mono and the mp3 will always be stereo.

I've read that if you "Just allocate a buffer twice the size of the original PCM data, and for every sample in the original buffer put it twice in the new buffer"

short[] stereoWavBuffer = new short[minBufferSize];
int k = 1;
for (int j = 0; j < minBufferSize / 2; j += 2)
{
    stereoWavBuffer[j] = wavBuffer[j];
    stereoWavBuffer[k] = wavBuffer[k];
     k += 2;

                }
                // TO DO -  Add the 2 buffers together

                for (int i = 0; i < minBufferSize; i++){
                    mixedBuffer[i] = (short)(mp3Buffer[i] + stereoWavBuffer[i]);
                }


                track.write(mixedBuffer, 0, minBufferSize); 
}

How can I accomplish this? I tried this but the wav audio now is at regular speed but sounds like chipmunk.

nawlrus
  • 777
  • 1
  • 13
  • 27
  • Are you saying that one buffer of `minBufferSize` is N seconds of audio but another one is 2N seconds of audio? – Gabe Apr 07 '12 at 17:01
  • I updated the question, after research it seems its better to just convert the mono to stereo but I am still having issues. minbufferSize is N seconds of audio in stereo. So when I mix the wavbuffer in 1:1, it plays way too fast. – nawlrus Apr 07 '12 at 19:05
  • What does the operation with the `mixedBuffer` do? If you just add one sample to another and round the result to fit into the 16 bits, you won't get anything good. You have to scale the result. As for the raw WAV data, yes, you have to just interleavve the samples (assuming you've fixed the data headers). – Malcolm Apr 07 '12 at 19:34
  • With mixed buffer I am just adding the shorts from each audio buffer together. I am then outputting the mixedbuffer to the audiotrack for playback. I also used FilterInputStream to remove the wav header so its just straight audio. – nawlrus Apr 07 '12 at 19:43

1 Answers1

2

It looks to me as if your first for loop should be

j < minBufferSize - 1

/2 would mean you will never read all of of the wave buffer or write your entire stereo buffer, - even if you only read half the wave buffer because that's all the data since it's mono you still need to write the entire stereo buffer. Also you need to increment J by 1 not 2 so you read each mono sample.

The speed issue appears to be because you should set stereowavebuffer at j and k both equal to wavebuffer at j. it seems that you are in fact just duplicating half of the original mono file. and then playing it back as stereo (ie: double the byterate).

I would think the first loop should look something more like this

int k = 0;
for (int j = 0; j < minBufferSize / 2; j++) //Assuming you only have half a buffer since mono???
{
    stereoWavBuffer[k] = wavBuffer[j];
    stereoWavBuffer[k+1] = wavBuffer[j];
     k += 2;
}

-edited to fix bad ipad typing!

Mark Willsher
  • 666
  • 7
  • 14
  • Holy crap. thank you so much. That worked. This is my first time dealing with audio so my logic was completely off. Thank you so much!! – nawlrus Apr 07 '12 at 22:04