stuck trying to point libltc to audio codec buffer !!

A project log for Arduino TIMECODE smpte LTC reader generator SHIELD

Using libltc to make a SMPTE Time Code Receiver/Generator for Arduino !

ben bilesben biles 11/18/2015 at 22:394 Comments

The two crucial lines are below. the first copys the samples from signed 16bit int to unsigned 8bit char for libltc.

OK, seams like the the Arduino UNO cannot copy the data quick enough as it just hangs the MC.

Maybe I need to hack AudioCodec.h to copy from 16bit int to unsigned 8 bit char for libltc.

would much appreciate it if anyone has any ideas?


unsigned char sample = ((right_in + 32768) >> 8) & 0xff; // signed 16bit to unsigned 8bit char
ltc_decoder_write (decoder, &sample, 1, 0);


heres the whole sketch.

// LTC TIMECODE decode from audio input and print timecode to console

// setup codec parameters
// must be done before #includes
// see readme file in libraries folder for explanations
#define SAMPLE_RATE 8 // 8kHz (WM8731@12.288MHz, Arduino@16MHz) ) mkc 9/15/13
#define ADCS 0 // use no ADCs (potentiometers)
#define ADCHPD 1 // High pass filter on the codec on/off
// WM8731 Microphone control
#define MUTEMIC 0 // disable MUTEMIC
#define INSEL 1 // enable MIC input
#define MICBOOST 0 // enable MICBOOST
#define BYPASS 0 // Bypass LINEIN
#define DACSEL 1 // Select DAC for audio loopback
#define SIDETONE 0 // Deselect SIDETONE
#define SIDEATT 0

// include necessary libraries
#include <Wire.h>
#include <SPI.h>
#include <AudioCodec.h>

// define & include stuff that libltc needs here
#include "ltc.h"
#include "encoder.h"
#include "decoder.h"

#define BUFFER_SIZE (1024)

int samplesperframe = 320; // 8khz/ 25fps samples per frame
LTCDecoder *decoder; //

unsigned char samples = 00000000; // maybe faster to use temp variable ( when i try i get errors )

/// end difine things for libltc

// create data variables for audio transfer
// even though there is no input needed, the codec requires stereo data
int left_in = 0; // in from codec (LINE_IN)
int right_in = 0;
int left_out = 0; // out to codec (HP_OUT)
int right_out = 0;

void setup()
// call this last if you are setting up other things
AudioCodec_init(); // setup codec and microcontroller registers

decoder = ltc_decoder_create(samplesperframe,0); // create ltc decoder called decoder with n samples per frame
void loop()

unsigned char sample = ((right_in + 32768) >> 8) & 0xff; // copy signed 16bit to unsigned 8bit char

ltc_decoder_write (decoder, &sample, 1, 0); // write sample to LIBLTC

LTCFrameExt frame;

while (ltc_decoder_read (decoder, &frame) > 0)
SMPTETimecode stime;
ltc_frame_to_time(&stime, &frame.ltc, 1);


// timer1 interrupt routine - all data processed here
ISR(TIMER1_COMPA_vect, ISR_NAKED){ // dont store any registers

// &'s are necessary on data_in variables

AudioCodec_data(&left_in, &right_in, left_out, right_out); //

// our sinewave is now in temp2
left_out = right_in; // put incoming audio on left channel
right_out = right_in; // put sinusoid out on right channel

reti(); // dont forget to return from the interrupt


ben biles wrote 07/07/2016 at 17:49 point

Hi KC , if you look at my last log I just finished building a shield for arduino Due which is 32bit. So now bringing in 2 x 32bit channels of unsigned audio samples from I2S. I moved the project to 32bit arduino to see if I was lacking memory etc,, now I'm shifting <<16 to make 16bit and sending that to LibLTC to have the 80bit LTC decoded. I'm using this , 

The I2S / codec is working well and this seams to change 32bit to 16bit.

samples16bit = ( rdat >> 16);  // copy rdat , unsigned 32bit int to 16bit unsigned int
ltc_decoder_write_u16  (decoder, &samples16bit,1, 0);  // write 16bits to LibLtc 16bit wrapper ready to be processed.

LibLTC works in unsigned 8 bit char , but it has a wrapper ltc_decoder_write_u16 which accepts incoming 16bit unsigned samples. well, LibLTC is'nt returning /printing any timcode yet !!! ! maybe I need to calculate how many samples to pass ltc_decoder_write_u16.,

The 3rd value is sample number. I think there is 1920 48khz samples in 1 second ( 25 frames ) ?

Its tricky , now i just pass 1 sample per I2S inturrupt from the I2S library but maybe I should pass 1920 ?

anywy , I feel I am close to making LTC decode work in real time , that is if I2S data is not completely wrong for LibLTC !

  Are you sure? yes | no

K.C. Lee wrote 07/07/2016 at 19:13 point

Congrats. I don't do Arduino.  Only pop in to comment about the16-bit to 8-bit conversion.

  Are you sure? yes | no

ben biles wrote 07/08/2016 at 01:42 point

no worries, will definatley take your advise and see if I can save some cycles by converting samples to 8bit first, thats if I can get around the timming problem on the Uno :) makes sence to throw away bits before making the addition. ( sounds cheaeper in cycles ) 

  Are you sure? yes | no

K.C. Lee wrote 07/07/2016 at 17:05 point

It might be a tiny bit faster if you "right shift" make a 8-bit number before converting it from signed to unsigned.  i.e. The 16-bit addition would now be an 8-bit.  A few cycles at most if the compiler is dumb.  It is not enough to make a difference.  Also check if the right shifts for 16-bit takes extra cycles having to sign extend the MSB.
I haven't touch 8-bit for a long time, so I don't remember these thing any more.

  Are you sure? yes | no