Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

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

  1. #1
    Junior Member
    Join Date
    Jul 2022
    Posts
    15

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

    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 by benyboy; 09-08-2022 at 03:25 AM.

  2. #2
    Junior Member
    Join Date
    Jul 2022
    Posts
    15

    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •