Convert Mono to Stereo

I have the following problem: I get a block of bytes (uint16_t *) representing the audio data, and the device generating them captures monaural sound, so obviously I have monaural data on 1 channel. I need to transfer this data to another device that expects alternating stereo data (so, 2 channels). What I want to do is basically duplicate 1 channel in the data, so that both stereo data channels will contain the same bytes. Can you point me to an efficient algorithm?

Thank you, e.

+6
source share
5 answers

If you just want stereo alternating patterns, you can use this function:

void interleave(const uint16_t * in_L, // mono input buffer (left channel) const uint16_t * in_R, // mono input buffer (right channel) uint16_t * out, // stereo output buffer const size_t num_samples) // number of samples { for (size_t i = 0; i < num_samples; ++i) { out[i * 2] = in_L[i]; out[i * 2 + 1] = in_R[i]; } } 

To generate stereo from one mono buffer, you just pass the same pointer to in_L and in_R, for example.

 interleave(mono_buffer, mono_buffer, stereo_buffer, num_samples); 
+13
source

Do you have the same index to both channels? If this violates restrict rules, use memcpy() ?

Sorry, but your question is generally broad. API? OS? CPUArchitectures?

+2
source

You might want to do the in-place conversion to save some memory. Depends on how little memory the device in question has. Therefore, you can use something like this instead of the Paul R approach:

 void interleave(uint16_t buf[], const int len) { for (int i = len / 2 - 1, j = len - 1; i > 0; --i) { buf[j--] = buf[i]; buf[j--] = buf[i]; } } 

When receiving audio data from a mono device, you allocate a buffer that is twice as large as necessary and transfers it to the mono device. This will fill half the mono audio buffer. Then you pass this buffer to the specified function, which converts it to stereo. And finally, you pass the buffer to stereo. You save extra allocation and therefore use 33% less memory for conversion.

+1
source

You will have to copy the buffer and duplicate it. Since you did not tell us the format of how it was completed, I cannot give the code, but it will look like a simple cycle loop.

 int_16* allocateInterleaved(int_16* data, int length) int i; int *copy = malloc(sizeof(int_16)*length*2); if(copy == NULL) { /* handle error */ } for(i =0; i<length; i++) { copy[2*i] = data[i]; copy[2*i+1] = data[i]; } return copy; } 

Forgive any blatant typos, my C is a little rusty. typdef in whatever type you need for a signed 16 bit in int_16. Remember to free the copy buffer, or better yet use it.

0
source

You need to alternate the data, but if the frame length exceeds one, any of the above solutions will not work. The solution below may take into account the variable frame length.

 void Interleave(BYTE* left, BYTE* right, BYTE* stereo,int numSamples_in, int frameSize) { int writeIndex = 0; for (size_t j = 0; j < numSamples_in; j++) { for (int k = 0; k < frameSize; k++) { int index = j * frameSize + k; stereo[k + writeIndex] = left[index]; stereo[k + writeIndex + frameSize] = right[index]; } writeIndex += 2 * frameSize; } } 
0
source

All Articles