ltc_decoder_write_u16
HI , I bought the ANSI C book and built audio IO for Arduino Due with I2S :) I am succesfully bringing in 32 bit samples from codec over I2S into Arduino Due with Passthough back out to Codec. The Due has a lot more power going for it than the arduino Uno so I don't have the inturupt issue now.
code here
https://github.com/benbiles/TimeCode-Shield/blob/master/timecodeshield
I am copying the samples to unsigned short int for ltc_decoder_write_u16 wrapper with
samples = ((rdat >> 16) & 0xffff); // copy rdat , unsigned long int to unsigned short int
then
ltc_decoder_write_u16 (decoder, &samples,1, 0); // write unsigned short to ltc_decoder_write_u16 ready to be processed by libltc.
I am getting nothing from this in the void loop()
LTCFrameExt frame; while (ltc_decoder_read (decoder, &frame) > 0) { SMPTETimecode stime; ltc_frame_to_time(&stime, &frame.ltc, 1); Serial.print("working?"); Serial.print(stime.hours); Serial.print(stime.mins); Serial.print(stime.secs); Serial.print(stime.frame);
this returns nothing.. Serial.print(ltc_decoder_read (decoder, &frame));
Serial.print(samples); brings a list of 16bit numbers that appear to be of maximum 65535 (unsigned short int)
Interestingly the numbers decrease in size when I maximise audio input volume and increase when I reduce volume. This is perhaps normal?
I tried converting samples back to 32bit with junk = ((samples << 16) & 0xffff); and sending junk back out of the codec and the timecode sounds normal.
I think I2S sends standard PCM samples so it should be compatible with LIBLTC.
Is there another variable I could print or test to see if ltc_decoder_write_u16 (decoder, &samples,1, 0); is actually sending the LTC library anything at all ?
I tried sending 8bit unsigned char also but no timecode returns from libltc as of yet.
Any ideas would be greatly appreciated :)
Hi benbiles,
Actually I think you are mis-using the LTC API. I think you also have some real-time issues in your code.
For example, what appends if you have let's say 10 interruptions of codecRxReadyInterrupt() routine in a row? The main loop will miss 10 samples because you write over the rdat value 10 times.
Also, documentation says about "ltc_decoder_read()": "@return 1 on success or 0 when no frames queued."
If the ltc_decoder_read() return 0 at the first iteration, it means that you didn't fed the ltc_decoder_write() with enough samples. Indeed, you are feeding only one sample each time to ltc_decoder_write.
To my mind, you are creating a huge overhead by feeding the LTC decoder this way. You better have to create a ping-pong buffer (check on google, keywords 'ping-pong buffer' or 'multiple buffering') that stores let's say 16384 samples in a temporary buffer, and feed the ltc_decoder with these samples in a row. You can tune up the size (by decreasing it) of the buffer if you really need real-time decoding. For example in my app, I can achieve good latency with 4096 samples.