Audio Library

Status
Not open for further replies.
Per-sample processing, or even variable or mixed size block processing is outside the scope of this library.

I noticed there are constants for the block size in the library though. So while variable or mixed block size may by out of the scope, what about using a much smaller fixed block size for everything? Is that supported? And what would selecting a smaller block size affect? The SD card read function I presume reads fixed blocks of 512 bytes, so a smaller audio block size I'd think would not affect the speed at which data can be streamed off the card. It would however I presume allow one to lower the latency from input to processing to output.
 
@scswift :smaller block size = less time(=less cpu cycles) to mangle with the blocks, i don't think that using 64, or even 32 sample block sizes could cause other difficulties.

@Paul:

Thanks for the detailed run down of the mixing algo, that explanation was very helpful! And no offense, but I still think that You do not get what my main question was. Altrough half of my post is about per sample processing, and related stuff, it was clear for me since Your first reply that this lib is built around block processing, and there are no plans to change that. But also, in my first question, I didn't intend to ask about per sample processing. I wanted to ask from the beginning about the possibility of zero latency I/O passthrough , and in my second post i've also pointed out the built in capabilities of the SGTL5k to do exactly this , between the line in, and outputs, but do You see any possibilities to extend this on the mic input, too?I know that this misunderstanding is because my language capabilities, and i'm sorry for distractin You from real work. :)
 
Hey Kondi, I could write 'bits' to allow skipping I2S_OUT->MCU->I2S_IN which would reduce latency but also rules out use of any Audio Library objects to manipulate samples at all - the SGTL5000 does have DAP but enabling it and routing the audio via it adds some little latency of its own and there is some small latency in a direct ADC->DAC connection anyway.

Afaik there is no such thing as 'zero latency' in digital audio: http://en.wikipedia.org/wiki/Latency_(audio)#Latency_from_live_signal_processing
 
I noticed there are constants for the block size in the library though. .... what about using a much smaller fixed block size for everything? Is that supported?

Well, that depends on what you mean by "supported". If you're imagining I actually test the library with anything other than 128 sample blocks, the answer would be no. If "supported" means I think everything ought to work, again no. Most things probably will work, but some of the input or output objects probably don't probably adjust to other block sizes. But if "supported" means I'd accept pull requests to fix such problems, if the fixes didn't negatively impact performance at 128, then sure.
 
I wanted to ask from the beginning about the possibility of zero latency I/O passthrough , and in my second post i've also pointed out the built in capabilities of the SGTL5k to do exactly this , between the line in, and outputs, but do You see any possibilities to extend this on the mic input, too?

I really haven't done anything with the SGTL5000, other than get I2S input and output working. Right now, robsoles is the only person here who's done much with the SGTL5000. I'm going to keep focusing on the audio processing code inside Teensy.

However, I will say that I believe the best way to achieve a "zero latency I/O pass through" feature involves surrounding Teensy with analog opamps and analog switches that implement such a feature.
 
I was looking at the processor's datasheet to try to understand I2S, and it looks like there are two TX and two RX lines. That makes me think that it would be possible to talk to two audio boards at once, to get four channel audio.

Yes, I believe this may be possible on Teensy 3.1. Of course, it's unlikely to work with just 2 instances of the existing I2S object. New code would probably be needed. I believe there's a way to do it with only 1 DMA channel for all 4 audio channels, but using 2 linked DMA TCDs might be simpler to come up with the configuration.

Another minor issue is configuring the two I2S DACs. In hindsight, I probably should have brought the CTRL_ADR0 signal out to a pad with a trace to cut to separate it from ground and some way to solder a connection to 3.3V. Maybe I'll do it on a future PCB rev (but PJRC recently ordered many of the existing board, so that's quite some distance in the future). The I2S receive and transmit pins would also need to be routed to different pins. The current PCB doesn't make this easy, but of course it's not impossible.

Probably a simpler approach would be to connect the SDA and SCL signals to the other I2C port, or to the alternate pins and use the pin config registers to select which SGTL5000 chip you want to configure.
 
I've attributed one issue to the DC offsetting done in Audio.cpp, inside of AudioInputAnalog::update (line 1120).

Any ideas how this could be done better? I'd really like it to automatically find and subtract the DC level, so people can use a couple resistor and a capacitor and the code will adapt automatically to their DC bais.

Maybe an initial fast response to get the approx DC level, followed by a much slower response afterward?



Pete: I looked over PlayMidiTones example and tried a bunch of things, but I don't think the commented out sections apply anymore. "'class AudioInputAnalog' has no member named 'connect'"

Opps, sorry, that's some ancient leftover stuff. Early on I had envisioned a more dynamic connection system between the audio objects, with the common usage being a bunch of connect() calls in the setup() function. But that turned out to be just too complex. It also made for difficult-to-read syntax that just wasn't "Arduino like". Ultimately I scrapped that idea, but apparently I didn't clean up some of the earliest examples.
 
@robsoles: What You've described sounds good! I know that there is no real zero latency in DSP, near-zero (sub ms) latencies are adequate. But this would be kind of useless, without being able to process the samples. For example, to be able to record to the SD. I think it's a fairly reasonable demand, for a recorder (or any application that does not intend to manipulate the audio stream "real time"), to not introduce ~6ms latency n the signal chain. What do You say about the feasibility?

I've tried Your sketch with Your fork of the audio library. with the volume @0, now the output of mysine is omitted. Neat :)

@Paul: Yes, or using a D.I box to split the signal before the teensy would be the best case, since there would be no quality degradation introduced. But if sub ms latency is still adequate in the signal chain (its still far better than ~6ms), then people could use this feature out of the box.

And please don't think that i'm bitching about this latency stuff. But the t3 + audio board capabilities are superb, and soon more and more people will notice this, and will try to utilize it in their projects, the latency topic will be very popular.

I realized very soon that this audio library is not the best for my current project. But a mic pre, and a decent 16bit ADC is necessarry, so still the audio board is the best and easiest solution. I do not intend to manipulate the signal, even the output is not neccessarry. But discussing , and clearing out the possibility of things like direct pass through I think is very helpful not just for me, but for others too
 
Last edited:
You might look into the Open Music Labs Codec Shield. I believe their examples work on a single sample without any buffering in the microcontroller. Of course, it's very limited in capability due to this software, even when used with the Maple board, but if all you need is simple processing with minimal latency, maybe it can work for you?
 
Thanks for the advice, but I need the computing power that T3 have, also the form factor of Your product :) And I'm sure that what I'm after could be accomplished by the T3+SGTL combo. But the Wolfson chip looks promising, with the 24bit capabilities (and as i can see in the datasheet, its has DAP capabilities between the mic input and the outputs)
 
Last edited:
I've merged all of robsoles and el supremo's changes. There were a couple merge conflicts, so please take a quick look to make sure I resolved them ok?

Tomorrow I'm going to split the code into multiple .cpp and .h files. Dumping all the code into two giant files was a quick and dirty way to get this project started, but obviously it's not a workable approach now that the code size has grown.

If anyone has any code changes, please submit pull requests ASAP, even if your code is broken!

Edit: send a pull request as long as the library compiles and it doesn't break other stuff... get it in now, before I change all the filenames. I don't want anyone's changes to get stranded by this reorganization.
 
Last edited:
I've added a pull request for an audio sweep function. The user can specify the start and end frequencies and the length of time of the sweep. It takes 82% of the processor so there won't be much else going on :) I'll try to speed it up.
Oh rats. I've just realized I haven't added the test function. Will add that ASAP.

I've found an anomaly in my Flange effect code and am trying to track down why it is there but the effect seems to work anyway.

Pete
 
@saxen

This is the spectrum of a 5kHz signal from AudioSynthWaveform:
PlaySynthSine_5000_spectrum.gif



and this is the spectrum of a 5kHz signal from my code which uses the arm sine function.
my_sine_5000_1.gif


The cubic interpolation used by the arm sine function will produce better results than linear interpolation but it takes a bit more cpu time. AudioSynthWaveform uses up to 2% whereas my arm sine version uses 6%.



Once the processor usage exceeds 100 you won't be able to produce output buffers fast enough and the missing buffers will be replaced with zeros which will distort the output audio.

Pete

Hi Pete,
thanks for your answers. I'm gonna give a try to the arm sine function!

Enrico
 
@saxen: I've submitted my version of AudioSynthWaveform to Paul as a pull request. If he accepts it, it generates the sine wave with arm_sin_q15 and the other three waveforms are generated without using tables.
It also includes the ability (with the set_ramp_length function) to ramp the beginning and end of a sine wave so that it doesn't "thump".

Pete
 
Pete, I've merged your latest. There are some changes I'd like to see, but for the moment it's much more important to just get all the code reorganized.

Long-term, I'd like to see the ramp functions as a separate object, rather than built into the waveform generator. Eventually, I want to create at least a few different types of envelope objects. Over time, many other sound generators will be created, so I'd like to see a model where sound originates from "input", "play" or "synth" objects, and is modified by "effect" objects. A design goal is to keep these functions in separate objects, so people can connect them together in new ways or implement replacements for one part while reusing all the rest.
 
Hey Paul, taking current copy of the library (from https://github.com/PaulStoffregen/Audio) and trying to compile examples (tried CalcBiquadToneControl.ino & FFT.ino) has lots of warnings (may not have been quite as many before) and then fails with
compiler said:
In file included from C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:1:0:
C:\bin\arduino-1.0.5-r2\libraries\Audio\Audio.h:715:0: warning: "DELAY_PASSTHRU" redefined [enabled by default]
In file included from C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:1:0:
C:\bin\arduino-1.0.5-r2\libraries\Audio\Audio.h:118:0: note: this is the location of the previous definition
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp: In member function 'void AudioOutputAnalog::begin()':
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:35:2: error: 'DMA_TCD4_SADDR' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:36:2: error: 'DMA_TCD4_SOFF' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:37:2: error: 'DMA_TCD4_ATTR' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:38:2: error: 'DMA_TCD4_NBYTES_MLNO' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:39:2: error: 'DMA_TCD4_SLAST' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:40:2: error: 'DMA_TCD4_DADDR' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:41:2: error: 'DMA_TCD4_DOFF' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:42:2: error: 'DMA_TCD4_CITER_ELINKNO' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:43:2: error: 'DMA_TCD4_DLASTSGA' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:44:2: error: 'DMA_TCD4_BITER_ELINKNO' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:45:2: error: 'DMA_TCD4_CSR' was not declared in this scope
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp: In function 'void dma_ch4_isr()':
C:\bin\arduino-1.0.5-r2\libraries\Audio\output_dac.cpp:96:20: error: 'DMA_TCD4_SADDR' was not declared in this scope
 
Install Teensyduino 1.18. Those were missing from earlier versions.

(and I removed the kludge that skipped compiling that code if you had an old version installed)
 
I've been rearranging the library today. It's now in many smaller, more manageable files.

I'm going to rename some of the objects to fit a more uniform naming scheme. That's going to cause incompatibility with any existing sketches.

Hopefully by tomorrow I'll be done with changes that break stuff....
 
I've reorganized the library today. I also just put open source license headers on all the files I originated.

Pete, are you ok with the MIT license for your contributions?

If anyone has any open source license input, now is the time....
 
Rename away, when you are done I will (1) sync the changes to my fork (again), (2) check for breakage in anything I have submitted, (3) add some more stuff primarily in control_sgtl5000.* and (4) submit a new pull request after more testing.
 
I've been rearranging the library today. It's now in many smaller, more manageable files.

I'm going to rename some of the objects to fit a more uniform naming scheme. That's going to cause incompatibility with any existing sketches.
I really appreciate consistancy, Paul! I've had to go through some libraries and rename stuff and such, but it sure makes code easier to understand. :)

I'm looking forward to getting one of your audio shields, and some more Teensy 3.1 boards. :)

8-Dale
 
Status
Not open for further replies.
Back
Top