audio decoder needs to de-interleave 2 channels and output to teensy

benyboy

Member
Hi , I have made a PTP audio link using 2 x teensy 4.1 and working audio boards.

I am using opus compression which is working in mono in various bandwidths over my RF modules.

I am now attempting to configure stereo.

The opus encoder requires interleaved audio samples for stereo input. I have attempted this like this.

getData() is called from the transmitter.ino file and update is called as a teensy heart beat.

the encoder outputs twice the number of encoded compressed bytes as in mono so this part maybe working !

Code:
uint8_t *AudioOutputOpusEnc::getData()
{
	encoder_compressed_frame_size = 0;
	return encoder_frame_buf_compressed_interleavedStereo;
}


void AudioOutputOpusEnc::update(void)
{
	audio_block_t *block;
	audio_block_t* block2;


	block = receiveReadOnly(0);
	if (block) {
		if(encoderInitialised)
			{

			memcpy(encoder_frame_buf_uncompressed_LEFT, block->data, CONFIG_AUDIO_FRAME_SIZE_SAMPLES);
			
			}
		release(block);
	}

	/* process 2nd block if it exists  */
	block = receiveReadOnly(1);
	if (block) {
		if (encoderInitialised)
		{

			memcpy(encoder_frame_buf_uncompressed_RIGHT, block->data, CONFIG_AUDIO_FRAME_SIZE_SAMPLES);
			
		}
		release(block);
	}

	/*  interleave the 2 x audio channels into stereo here and pass to OPUS encoder */

	int BufSize = CONFIG_AUDIO_FRAME_SIZE_SAMPLES * sizeof(int16_t); // stereo interleaved is twice the size

	// Serial.println(BufSize*2);

	for ( int i = 0; i <= BufSize; i=i+2 ) 
	{ 
		encoder_frame_buf_uncompressed_interleavedStereo[i] = encoder_frame_buf_uncompressed_LEFT[i];
		encoder_frame_buf_uncompressed_interleavedStereo[i] = encoder_frame_buf_uncompressed_RIGHT[i + 1];
	}

	encoder_compressed_frame_size = opus_encode(m_opus_encoder_state, encoder_frame_buf_uncompressed_interleavedStereo, CONFIG_AUDIO_FRAME_SIZE_SAMPLES * sizeof(int16_t), encoder_frame_buf_compressed_interleavedStereo, sizeof(encoder_frame_buf_compressed_interleavedStereo));
	
	/* frame size should be double size of mono now */
	Serial.println(encoder_compressed_frame_size);

}



decoder to audio outputs is where I get stuck. Put data is called from the reciever.ino file when
the right amount of compressed audio packets are received.

I need to de-interleave the samples into channel 1 & 2.



Code:
int32_t AudioInputOpusDec::putData(uint8_t* compressedBuffer, int32_t bufferSize)
{
	__disable_irq();
	memcpy(decoder_frame_buf_compressed_stereoInterleaved, compressedBuffer, bufferSize);
	decoder_compressed_frame_size = bufferSize;
	__enable_irq();
	return inputPacketPhase;
}


void AudioInputOpusDec::update(void)
{
	inputPacketPhase = 0;

	audio_block_t *block;
	

	block = allocate();

	if (block) {

		/* this was in the mono block */
		if (decoderInitialised)
		{
			decoder_decompressed_frame_size = opus_decode(m_opus_decoder_state, decoder_frame_buf_compressed_stereoInterleaved, decoder_compressed_frame_size, decoder_frame_buf_uncompressed_stereoInterleaved, CONFIG_AUDIO_FRAME_SIZE_SAMPLES * 2, 0);

			Serial.print("decoder_decompressed_frame_size =");
			Serial.printf(" %d", decoder_decompressed_frame_size);
			Serial.println();
                 }

			int AA = 0; // 0,2,4,6,8, etc
			

			for (int x = 0; x <= decoder_decompressed_frame_size; x = x + 2)
			{
				block->data[x] = decoder_frame_buf_uncompressed_stereoInterleaved[AA];
				AA = AA + 2;
	
			}

		
			transmit(block,0);

			int BB = 1;  // 1.3.5.7.9. etc

			for (int y = 0; y <= decoder_decompressed_frame_size; y = y + 2)
			{
		    block->data[y] = decoder_frame_buf_uncompressed_stereoInterleaved[BB];
				BB = BB + 2;
			}
			
			
			transmit(block, 1);

			release(block);
		
	}

	}



I tried to use 2 x audio_block_t *block but it did'nt really work.

Now I'm trying to transmit(block,0); and transmit(block,1); but I don't release(block); until after I copy to both.

Is there a better way to send LEFT and RIGHT channel samples to channel 1 and channel 2 ?

I have audio connections setup like this

AudioConnection patchCord1(opusDecoder, 0, i2s_out, 0);
AudioConnection patchCord2(opusDecoder, 1, i2s_out, 1);

am I getting this totally wrong ?

happy to post the entire code , but its big so I'll try and upload it all to github now.

Any ideas very much appreciated.
 
Last edited:
scrapped this and now just sending 2 x mono packets

scrapped this and now just sending 2 x mono packets for LEFT and RIGHT channels.
 
Back
Top