Reading Microphone Data by Polling using ALSA [or V4L2]
To prevent the snd_pcm_read*()
calls from blocking, enable non-blocking mode with snd_pcm_nonblock().
To get pollable file descriptors, call snd_pcm_poll_descriptors_count() and snd_pcm_poll_descriptors().
It is possible to have multiple descriptors because some plugins might implement notifications differently.
To translate the result of a poll()
on those descriptors back into a POLLIN
/POLLOUT
value, call snd_pcm_poll_descriptors_revents().
How to fill ALSA buffer in timely manner
When the PCM device is in blocking mode (the default), snd_pcm_write*()
will wait until all bytes have actually been written to the buffer. Unplayed samples never are overwritten.
When the PCM device is in non-blocking mode, snd_pcm_write*()
will return how many frames have actually been written (or return -EAGAIN if the buffer is completely full). To wait for some space to become available, use poll()
, which allows to use an event loop that waits for multiple types of events. (See that answer for details.)
Java Sound API: Attempt to Do Live Microphone Input Monitoring is Slow
There is more than one buffer involved!
When you open the SourceDataLine and TargetDataLine, I'd recommend using the form where you specify the buffer size. But I don't know what size to recommend. I haven't played around with this enough to know what the optimum size is for safely piping microphone input--my experience is more with real-time synthesis.
Anyway, how about this: define the length of data[] and use the same length in your line opening methods. Try numbers like 1024 or multiples (while making sure the number of bytes can be evenly divided by the per-frame number of bytes which looks to be 4 according to the format you are using).
int bufferLen = 1024 * 4; // experiment with buffer size here
byte[] data = new byte[bufferLen];
sourceLine.open(bufferLen);
targetLine.open(bufferLen);
Also, maybe code in your run() would be better placed elsewhere so as not to add to the required processing before the piping can even start. The array data[] and int readBytes could be instance variables and ready to roll rather than being dinked with in the run(), potentially adding to the latency.
Those are things I'd try, anyway.
How to fill ALSA buffer in timely manner
When the PCM device is in blocking mode (the default), snd_pcm_write*()
will wait until all bytes have actually been written to the buffer. Unplayed samples never are overwritten.
When the PCM device is in non-blocking mode, snd_pcm_write*()
will return how many frames have actually been written (or return -EAGAIN if the buffer is completely full). To wait for some space to become available, use poll()
, which allows to use an event loop that waits for multiple types of events. (See that answer for details.)
Alsa full duplex communication
When the application has to wait for a PCM device, it goes to sleep and gets woken up at the next period boundary. Therefore, the optimal size to read/write is one period (or a multiple of that).
You should read/write sample data as soon as some frames are available.
To reduce the chances of an over/underrun, increase the buffer size.
(On capture devices, increasing the buffer size does not increase latency.)
Related Topics
Auto-Start Program at Login in Angstrom on Beagleboard
Which Tool Has Replaced Gatttool in Bluez5
Fortran: How to Get The Node Name of a Cluster
Eclipse Kura Installation on Raspberry Pi 3
Make Uses "Cc" Instead of "Arm-None-Eabi-As"
What Is Difference Between Sched_Batch and Sched_Other Scheduling
Docker Non-Root Bind-Mount Permissions, with -Userns-Remap
Xdotool Type Takes Ages and Causes Entire Desktop to Freeze
How to Add a Ppa Repository Using Ansible
Why Does Sed Leave Many Files Around
Inconsistent Systemd Startup of Freeswitch
Rename Multiple Files - Linux/Ubuntu
How to Ensure Data Reaches Storage, Bypassing Memory/Cache/Buffered-Io
What Is The 'Tr' Command in Windows
Code for Wait_Event_Interruptible
What Happens When I Sudo Bash -C