Audio Library

Status
Not open for further replies.
Nantonos, most higher end DACs seem to use differential current outputs, so it would just be a small tweak to the output section to accommodate balanced outputs as opposed to ground referenced outputs.

The real question is how good it needs to be. I don't think that true 'audiophile' quality is going to be a worthwhile goal, especially in a Teensy style form factor. I was imagining something that would be at least a moderate improvement over the SGTL5000 (eg support for 192kHz sampling, better SNR, etc), but not so much better that it would require the extreme attention to detail that is necessary to achieve 'audiophile' performance. It really depends on what people are looking for.

Matto, a separate power supply would likely help with any digital power supply noise from the Teensy that makes it onto the audio board, but it sounds more like a bad ground connection somewhere. It could also depend on what else is connected to the audioboard, ie speakers vs headphones, etc.
 
I've been considering having PJRC make a second audio shield for audiophile applications. Or it might be an unassembled or partially assembled (SMT parts soldered) kit.
.... so I'd really like to hear some input from anyone interested in this high end audio, about what sorts of ways they'd actually use Teesny and such a shield. What types of connections to other stuff than the DAC shield are the most important part.

Price is also going to be an issue. Anything "audiophile" is going to need expensive parts. My gut feeling it to try to keep the shield under $100 retail price. With a high end DAC, optical or transformer isolation, jitter-free clock generation, and expensive opamps for top quality output filtering, $100 might not be very realistic?

One niche market for high-sample-rate ADC/DAC peripherals is in nature recording and related projects. Many creatures smaller than people have acoustic interactions with the physical world that are very rich in frequencies well above the high end of the range of what's audible to humans. In this realm most of the current options for amateur hobbyists go directly from around $20 for detectors that indicate if there is currently any noise at or around frequency X to multi-thousand dollar systems for microphones with relatively flat frequency response curves through 80kHz and recording sample rates greater than 192kHz.

Building something in the sub-$100 range that would support working with even 16-bit data at >= 192kHz would make a lot of these projects possible for people who can't or don't want to invest many thousands of dollars for the truly high-end stuff. And, really, who wants to leave a $2000 recording setup in a weatherproof box in the woods for a week?
 
robsoles

I have gently modified your analyze_peakdetect to return level in db ( about 6 lines of code ). Code is working well, tracks a HP TIMS meter to about .1db has a little more jitter then I think it needs to have but that is a topic for another conversation. It strikes me that adding another method to your object would be very conservative of code? I think I can figure out how to add analyze_db to the library but would not want to do that using 98% of your code and 2% of mine without your explicit permission. Will also have to embark on the github, pull request, OOP, learning curve :)
 
When I contributed it to a publicly hosted library I implicitly gave my permission for anybody who sees it to treat it how they want to, inclusive of adding or modifying anything in it (and any other contrib I ever managed or go on to manage) as much as they like and either keep that for themselves or publicly contribute their changes as well.

Which scale(s) of dB are you planning to support?

Edit: Some reasonable explanation of differences between dB, dBu & dBV could be worth reading; Just for where they mention dB http://www.ovnilab.com/articles/linelevel.shtml, and for specifics of dBu & dBV http://www.sengpielaudio.com/calculator-db-volt.htm
 
Last edited:
Hello,
I was wondering if it would be possible to have a method to seek to a specific point in time in a wav file ?
I'm building a system where I need audio to be in sync between different stations that are a couple meters apart. I'm currently using Xbees (the 802.15.4 type) It seems to work fine but sometimes packets get lost and and the audio on one of the stations will not start. If I could send a periodic heartbeat and seek to a specific timestamp in the file I think it could help a lot...
 
raw audio to sd card

Hello,

with no means to hijack this thread, I have been working on a AudioRecordSdRaw class and so far my progress has been good. I use a different CODEC then the teenst audio board but it works in the same way. I am experiencing a little discomfort in the hearing region of my body when I playback on I2C what I've recorded on my SD card that came from the I2S itself. (I2S->SD then SD->I2S). The symptoms are constant little glitches (like little pop on an old turntable every 100-200 ms or so) and a noticeable speed-up of the tempo (pitch seems to be the same). I am suspecting the SD card which is a class4 pretty crappy I think but I would like more inputs on what else could be wrong. Here is my update function:

Code:
void AudioRecordSdRaw::update(void)
{
	unsigned int i, n;
	audio_block_t *block;

	// only update if we're recording
	if (!recording) return;

	// receive block from transmit
	block = receiveReadOnly(0); //channel 0?
	//block = receiveWritable(0);
	
	if (!block) return;

// meh.......... new file this does not apply
//	if (rawfile.available()) {
		// we can write more data to the file...	

		//__disable_irq();
		
		// write data for 44100Hz 16bit mono raw		

		// crap, block->data is int16_t and write is int8_t....
		n = rawfile.write((uint8_t*)block->data, AUDIO_BLOCK_SAMPLES*2);
		
//		Serial.print(n, DEC);
		
		//int8_t buffer[AUDIO_BLOCK_SAMPLES*2];
		

		
// uncomment for chipmunks speed clusterfuck
//			rawfile.flush();

//__disable_irq();		
		file_offset += n;
	
		// maybe wrong...
		//file_size += AUDIO_BLOCK_SAMPLES*2;
//__enable_irq();
		
//	} else {
//		rawfile.close();
//		recording = false;
//	}

	release(block);
}

thanks for the help!
Mevon
 
When I contributed it to a publicly hosted library I implicitly gave my permission for anybody who sees it to treat it how they want to, inclusive of adding or modifying anything in it (and any other contrib I ever managed or go on to manage) as much as they like and either keep that for themselves or publicly contribute their changes as well.

Which scale(s) of dB are you planning to support?

Edit: Some reasonable explanation of differences between dB, dBu & dBV could be worth reading; Just for where they mention dB http://www.ovnilab.com/articles/linelevel.shtml, and for specifics of dBu & dBV http://www.sengpielaudio.com/calculator-db-volt.htm

At the moment dbm referanced to 600 ohm, most of what I will do involves driving telco twisted pair.
 
I tried with a platinum II sdhc uhs-i class10 200x 30mb/s 8go card and it seems it's only making it worst. Somehow, my sampling is faster then the 44.1kHz and is worst when the sd card has faster capabilities. I am assuming that the OutpuI2S or InputI2S is taking responsability for updating all audio objects, maybe I need a timed based interrupt to record because the update() function seems to be nothing constant or synchronized enough to write on the sd at proper speed. any help would be appreciated, please.

Thank you,
Mevon
 
also seems the block size when I reformat the sd card has something to do. I guess it helps when the block size is larger so less time is spent writting blocks on the sd card.

please help me, :S

Mevon
 
i2s input to sd raw

trouble seems in the InputI2S where it cannot take update responsibility if an OutputI2S is not created

in the begin() of InputI2S object:

Code:
// TODO: should we set & clear the I2S_RCSR_SR bit here?
	AudioOutputI2S::config_i2s();

To me, it seems InputI2S and OutputI2S are not playing nice together. Playing a sine and recording it, it is clear that someone is dropping the ball somewhere, some data are missing in the plot. I'm guessing it may be some other arduino functions running in the background somewhere that glitch the interrupts but in my sketch all is done in the setup() function. I would like to test with only the InputI2S object running but seems it lacks the update responsibility without the OutputI2S's begin() function.

any hints anyone?
Mevon
 
Or can the led (pin 13) on the I2S0_RXD pin cause a latency that causes some packets to be dropped at 44100Hz sampling?

Mevon
 
So it seems having a faster sd card takes more time to write data on it then with a crappy class4 card... Not writing to the SD card "eliminates" the glitches (I would write all the bytes theoretically as opposed to missing 100k of data when I actually do the writes on the card). Im looking for a faster SPI library maybe this will solve it.

Mevon
 
I'm wondering if the AudioInputAnalog can be used at the same time as OctoWS2811 - they both seem to use DMA but I think on a Teensy 3.1 they seem to use different DMA channels?

I am just planning on using the audio input for FFT analysis (ie no audio output, just visual output), and I'm finding that there appears to be some hysteresis. The same sort of quiet conditions are resulting in different FFT256 results after it's been running for a minute or two, just watching the lower frequency buckets they noticeable increase in value after resetting my Teensy.
 
record raw to sd card

Hi everyone,

so the SD library is too slow to write an audio block while doing the update(), received blocks on I2S are missed and glitches in the sound are appearing. What would be better here? Add some kind of double buffering in the InputI2S object or have a FIFO for blocks in the arduino project or maybe even in the AudioRecordSdRaw object to buffer the blocks generated by InputI2S while the writing to the SD card is pending?

Please advise!
Mevon
 
Hi everyone,

so the SD library is too slow to write an audio block while doing the update(), received blocks on I2S are missed and glitches in the sound are appearing. What would be better here? Add some kind of double buffering in the InputI2S object or have a FIFO for blocks in the arduino project or maybe even in the AudioRecordSdRaw object to buffer the blocks generated by InputI2S while the writing to the SD card is pending?

Please advise!
Mevon

Or maybe create an in-between object like AudioPlayQueue object that has a buffer for blocks (5 or 10 blocks, maybe 20 = 5kb is acceptable in the T3.1) and in the loop() or main() we pool to empty the queue to the SD card. That way update() done in timed ISR won't stall while waiting for the SD card to write its data... Yes? Yeah!

Mevon
 
Hi Mevon

I'd be interested to see whether you solve this...

I asked about recording back on page 20... follow the discussion from there...

Pete 'el supremo' advised that he'd tried and couldn't record directly to the SD card without glitching...

His advice was to add a W25Q128FV 16Mbyte flash chip to the Audio Shield, record to that and then write that file to the SD...

He made his development code available via the forum... currently it's being integrated in the Audio library by Paul... shouldn't be too long 'til it's available according to past posts.

I've installed the W25Q128FV and tested Pete's code and can confirm I can record perfectly well to the SD card...
 
lengthMillis() & positionMillis()

Hi

Can someone please advise on how to implement lengthMillis() and positionMillis()...

I want to know how long a wav file I'm playing is and how far along playing it I am...

Both wav.lengthMillis() and wav.positionMillis() return 0...

The function in the library code is:

uint32_t AudioPlaySdWav::lengthMillis(void)
{
if (state >= 8) return 0;
return ((uint64_t)total_length * bytes2millis) >> 32;
}

Under what conditions do I get a state < 8?

Best

Prodical
 
A state >= 8 means that either the WAV header is still being parsed or that playing has stopped, in which case the length is either not yet known or not useful (maybe?).
If the state < 8 the header has been parsed and the file is being played.

Note that isPlaying() simply does this: return (state < 8). So, if isPlaying() returns true then lengthMillis and positionMillis should return a non-zero value.

Pete
 
seek to a specific point in a file ?
That would be possible, especially if you didn't mind that playing started at the nearest buffer boundary before, or at, the required point. If you wanted exactly the specified location and it didn't fall on a buffer boundary it would add some cpu load to shuffle the samples. (But I'm not volunteering to do it :) )

Pete
 
Nice to know it could be possible. I would be useful to sync multiple Teensys/Audio boards for very long files.
 
Issues playing back audio files from SD

Hi

I wonder if anyone has a similar experience and can advise?

I have a several short (max 5 seconds) mono, 44.1k 16bit WAV files on the SD with names in 8.3 format...

My code randomly chooses a file name and plays it on a button press...

Initially I had no issues with playback at all... but recently (and admittedly as my sketch has increased in complexity) I frequently experience an issue where part way through playing back a file I hear a burst of 'white' noise and then the audio adaptor fails to playback subsequent files. Most of the time this corrects itself after several more button presses.

I have a mode where file play back is immediately followed by an AudioSynthWaveform sine wave bleep - and in this case the tone plays even if the wav file doesn't.

Occasionally wav playback is interrupted by a burst of 'white' noise, then a constant high pitched noisy tone... and the only way to overcome this is to unplug the Teensy.

I've set memory quite high in case this was the issue - AudioMemory(20);

// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example

but this doesn't see to have any effect.

As an aside I can't actually locate the MemoryAndCpuUsage example - where is it?

Any thoughts as to why this might be and how to overcome it?

Best

Prodical
 
Initially I had no issues with playback at all... but recently (and admittedly as my sketch has increased in complexity) I frequently experience an issue where part way through playing back a file I hear a burst of 'white' noise and then the audio adaptor fails to playback subsequent files. Most of the time this corrects itself after several more button presses.

Any chance you could make a version of this program which reproduces the problem based only on automatic playing from delays, IntervalTimer or some other highly reproducible way? (not depending on user input)
 
Any chance you could make a version of this program which reproduces the problem based only on automatic playing from delays, IntervalTimer or some other highly reproducible way? (not depending on user input)

Hi. I'm using the StopWatch library anyway... so I'll use that. Leave it with me...
 
Status
Not open for further replies.
Back
Top