Lowest possible latency

Moderator: flatmax

robiwan
Posts: 59
Joined: Wed Jul 05, 2017 1:18 am

Re: Lowest possible latency

Post by robiwan » Wed Jul 12, 2017 8:23 pm

I have used Eigen before, so will probably use that as the front-end for FFTs, so C/C++ it is :)

Alas, I'm not very proficient in Linux/ALSA, so the plugin class certainly looks interesting. It's possible to create a standalone SO to load into ALSA with it ? Although, the plugin should be very simple, for starters it should support the number of inputs as the slave PCM device it connects to, with float samples in/out.

flatmax
Posts: 609
Joined: Sat Jul 23, 2016 11:39 pm

Re: Lowest possible latency

Post by flatmax » Wed Jul 12, 2017 9:17 pm

yes,

You can create your plugin which uses floats. Then in your .asoundrc you can create an input and output plugin to convert from native format to float on the input to your plugin. On the output same in reverse - create a plugin to convert from float back to the native format.

The chain is like so : Native application format -> toFloatPlug -> yourALSAPlug -> fromFloatPlug -> Native sound card format

Matt
Check out our audiophile quality crossovers : https://bit.ly/2kb1nzZ
Please review the Zero sound card on Amazon USA : https://www.amazon.com/dp/B075V1VNDD
---
Check out our new forum on github : https://github.com/Audio-Injector

robiwan
Posts: 59
Joined: Wed Jul 05, 2017 1:18 am

Re: Lowest possible latency

Post by robiwan » Sun Jul 16, 2017 1:30 am

Ok, I'm having a bit of a trouble, tried to record from the card, but I get nothing but silence:

> arecord -L
null
Discard all samples (playback) or generate zero samples (capture)
ladspa
pladspa
default:CARD=audioinjectorpi
audioinjector-pi-soundcard,
Default Audio Device
sysdefault:CARD=audioinjectorpi
audioinjector-pi-soundcard,
Default Audio Device
dmix:CARD=audioinjectorpi,DEV=0
audioinjector-pi-soundcard,
Direct sample mixing device
dsnoop:CARD=audioinjectorpi,DEV=0
audioinjector-pi-soundcard,
Direct sample snooping device
hw:CARD=audioinjectorpi,DEV=0
audioinjector-pi-soundcard,
Direct hardware device without any conversions
plughw:CARD=audioinjectorpi,DEV=0
audioinjector-pi-soundcard,
Hardware device with all software conversions

> arecord -D default -c 2 -f S32_LE -t wav -r 48000 test.wav

Ideas ?

The input knob is turned up to max ;) and alsamixer (Capture) is set to Line with 100 in capture level.

robiwan
Posts: 59
Joined: Wed Jul 05, 2017 1:18 am

Re: Lowest possible latency

Post by robiwan » Sun Jul 16, 2017 2:23 am

NEVERMIND! The input mux was set for Mic. A little confusing having the input mux on the Playback page of alsamixer ;)

robiwan
Posts: 59
Joined: Wed Jul 05, 2017 1:18 am

Re: Lowest possible latency

Post by robiwan » Sun Jul 16, 2017 3:12 am

Using the patest_wire from Portaudio, and paFramesPerBufferUnspecified + PA_ALSA_PERIODSIZE = 32 I can get reliable streaming. With 24 it seems a bit shaky, but that might relate to the Portaudio ALSA implementation, still, that should be a latency of about (32 * 2)/48000 ~ 1.33 ms. I might be able to push it by going directly via ALSA.

Maybe to use jackd to stream audio, don't know jack about that though (yet) :)

flatmax
Posts: 609
Joined: Sat Jul 23, 2016 11:39 pm

Re: Lowest possible latency

Post by flatmax » Sun Jul 16, 2017 2:08 pm

You should be able to reduce this with ALSA.

In this example it sets up pretty much what you want to do :
http://gtkiostream.flatmax.org/ALSAFull ... ample.html

I guess however you would want class member variables for implementing the FFT ?

You will need to include the Eigen FFT header :

Code: Select all

#include <unsupported/Eigen/FFT>
Then you would want your complex data like so :

Code: Select all

Eigen::Array<FFT<int>::Complex, Eigen::Dynamic, Eigen::Dynamic> INPUTAUDIO;
And the FFT :

Code: Select all

Eigen::FFT<int> fft;
Finally to implement the FFT in the process method :

Code: Select all

for (int i=0; i<inputAudio.cols(); i++)
    fft.fwd(INPUTAUDIO.col(i).data(), inputAudio.col(i).data(),inputAudio.rows());
Before you do that however make sure INPUTAUDIO is the same size as inputAudio.

Also do the same for your filter :

Code: Select all

Eigen::Array<int, Eigen::Dynamic, Eigen::Dynamic> h;
// load in the h data
Eigen::Array<FFT<int>::Complex, Eigen::Dynamic, Eigen::Dynamic> H(h.rows(), h.cols());
for (int i=0; i<h.cols(); i++)
    fft.fwd(H.col(i).data(), h.col(i).data(), h.rows());
Now in your process method, multiply H and INPUTAUDIO, perform the inv transform and there is your output for that window.

Matt
Check out our audiophile quality crossovers : https://bit.ly/2kb1nzZ
Please review the Zero sound card on Amazon USA : https://www.amazon.com/dp/B075V1VNDD
---
Check out our new forum on github : https://github.com/Audio-Injector

robiwan
Posts: 59
Joined: Wed Jul 05, 2017 1:18 am

Re: Lowest possible latency

Post by robiwan » Sun Jul 16, 2017 3:34 pm

Thanks!

Having been experimenting around a bit, I've decided to put the DSP inside a LADSPA plugin, and use the ALSA LADSPA PCM plugin to load it, works nicely with f.i. Mopidy. The ALSA full duplex example is needed though to pipe from input to output, so the full pipeline would be:

i2s_in -> alsa_in -> full duplex app -> alsa_out -> LADSPA plugin -> i2s_out (with appropriate conversions of course) . I hope this can be setup as full duplex, perhaps configured in alsa.conf ?

Are there any dependencies of the ALSA classes in gtkIOStream beyond ALSA itself ?

You don't happen to have stuff for LADSPA as well ? :)

flatmax
Posts: 609
Joined: Sat Jul 23, 2016 11:39 pm

Re: Lowest possible latency

Post by flatmax » Sun Jul 16, 2017 3:43 pm

The only dependencies are Eigen and fftw3.
You can optionally get Sox as well which might be useful.

I plan to do a tute on building installing and using gtkiostream for audio programming.

It is basically like so :

Code: Select all

sudo apt install libeigen3-dev libfftw3-dev libsox-dev

git clone	https://github.com/flatmax/gtkiostream.git
cd gtkiostream
./tools/autotools.sh 
./configure --disable-octave

make 
sudo make install
Check out our audiophile quality crossovers : https://bit.ly/2kb1nzZ
Please review the Zero sound card on Amazon USA : https://www.amazon.com/dp/B075V1VNDD
---
Check out our new forum on github : https://github.com/Audio-Injector

robiwan
Posts: 59
Joined: Wed Jul 05, 2017 1:18 am

Re: Lowest possible latency

Post by robiwan » Mon Jul 17, 2017 6:28 pm

Got everything to compile, and running the full duplex test I cannot get below 64 frames. I get:

latency = 0.000666667 s
opening the device hw:0
opening the device hw:0
func: fillParams
func: setAccess
func: setFormat
func: setChannels
func: setSampleRate
opening the device hw:0
opening the device hw:0
func: fillParams
func: setAccess
func: setFormat
func: setChannels
func: setSampleRate
opened the device func: getDeviceName
hw:0
func: fillParams
func: fillParams
func: setFormat
func: setFormat
func: setAccess
func: setAccess
func: setSampleRate
func: setSampleRate
func: setChannels
func: setChannels
func: setBufSize
func: setPeriodSize
func: setBufSize
func: setPeriodSize
func: setHWParams
func: getSWParams
func: setSWThreshold
func: setAvailMin
func: setSWParams
func: setHWParams
func: getSWParams
func: setSWThreshold
func: setAvailMin
func: setSWParams
-32
Broken pipe writeBuf overrun
-32
Broken pipe func: running
-32
Broken pipe func: close
func: drop
func: running
PCM::drop can't drop, not running
func: close
func: drop
func: running
PCM::drop can't drop, not running

I note that the compilation uses -O2, not -O3. Don't know if that should be significant..

robiwan
Posts: 59
Joined: Wed Jul 05, 2017 1:18 am

Re: Lowest possible latency

Post by robiwan » Mon Jul 17, 2017 6:51 pm

The full duplex test, is it using a polling thread or an ALSA callback ?

Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests