I have a microphone and I can record voice like so:
arecord test.wav -r 22050 -f S32_LE -V mono
So far so good. However, when a third party software that I'm using (which I think uses ffmpeg internally), wants to use the microphone it fails, since it does not use the above described parameters.
I tried now to move those parameters into my .asoundrc
so that they will be picked up by alsa.
The Alsa Wiki tells me that the plug
plugin can be used in order to specify the rate
and the format
:
A more complex tool for conversion is the pcm type plug. the syntax is:
type plug # Format adjusted PCM slave STR # Slave name (see pcm_slave) # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition [format STR] # Slave format (default nearest) or "unchanged" [channels INT] # Slave channels (default nearest) or "unchanged" [rate INT] # Slave rate (default nearest) or "unchanged" } route_policy STR # route policy for automatic ttable generation # STR can be 'default', 'average', 'copy', 'duplicate' # average: result is average of input channels # copy: only first channels are copied to destination # duplicate: duplicate first set of channels # default: copy policy, except for mono capture - sum ttable { # Transfer table (bidimensional compound of # cchannels * schannels numbers) CCHANNEL { SCHANNEL REAL # route value (0.0 ... 1.0) } }
So I setup a plugin like so:
pcm.!default {
type asym
playback.pcm {
type plug
slave.pcm "softvol"
}
capture.pcm {
type plug
slave {
pcm "plughw:0" # this works
rate 22050 # does not apply
format S32_LE # does not apply
}
}
}
The pcm "plughw:0"
gets picked up however, the rate and the format fall back to 8 Bit and 8000Hz. Also I have to specify -V Mono
so that I can record:
arecord test.wav -V mono
Recording WAVE 'test.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
############+ |
So unfortunately none of the required parameters can be added to my settings.
Update
I tried to record using ffmpeg
in an attempt to mimic what :
ffmpeg -f alsa -ac 1 -i plughw:0 output.wav -ar 22050 -f S32_LE
The recording starts but no audio is recorded and the rate and format are mixed up again:
aplay output2.wav
Playing WAVE 'output2.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
Update with asym
plugin
I did try an asymmetric approach as suggested.
pcm.my_mic {
type hw
card 0
channels 1
format S32_LE
}
pcm.duplex {
type asym
playback.pcm "dmixer"
capture.pcm "my_mic"
}
pcm.!default {
type plug
slave.pcm "duplex"
}
However, when I enter arecord test.wav
I'm asked for the format despite the fact that it's configured in the .asoundrc
.
When I do enter a format I get the following error:
arecord -f S32_LE
Recording WAVE 'stdin' : Signed 32 bit Little Endian, Rate 8000 Hz, Mono
ALSA lib pcm_params.c:2162:(snd1_pcm_hw_refine_slave) Slave PCM not usable
arecord: set_params:1270: Broken configuration for this PCM: no configurations available.
Update
With some ALSA magic by my friend Y.W. I was able to get arecord to work without parameters, however, it's still somehow using inferior settings when recording audio by default. The key here it seems was to map the mono signal of my I2s card to a stereo signal.
This is the .asoundrc
content:
# This section makes a reference to your I2S hardware, adjust the card name
# to what is shown in arecord -l after card x: before the name in []
# You may have to adjust channel count also but stick with default first
pcm.dmic_hw {
type hw
card raspisound
channels 2
format S32_LE
rate 48000
}
# This is the software volume control, it links to the hardware above and after
# saving the .asoundrc file you can type alsamixer, press F6 to select
# your I2S mic then F4 to set the recording volume and arrow up and down to adjust the volume
# After adjusting the volume - go for 50 percent at first, you can do something like
# arecord -D dmic_sv -c2 -r 48000 -f S32_LE -t wav -V mono -v myfile.wav
pcm.dmic_sv {
type softvol
slave.pcm dmic_hw
control {
name "Boost Capture Volume"
card raspisound
}
min_dB -3.0
max_dB 30.0
}
# This plugin converts the mono input to stereo.
pcm.mono2stereo {
type route
slave.pcm dmic_sv
slave.channels 2
# ttable.input_channel.output_channel volume_gain
ttable.0.0 1
ttable.0.1 1
}
# The "plug" plugin converts channels, rate and format on request.
# In our case it converts the 32 format to whatever the application request.
pcm.convert {
type plug
slave {
pcm mono2stereo
}
}
pcm.convertplayback {
type plug
slave {
pcm "hw:0"
}
}
# Default capture and playback devices
pcm.!default {
type asym
capture.pcm convert
playback.pcm convertplayback
}