Capture/Record Audio in Linux for Milliseconds - linux

arecord -d 10 sample.wav
Here, this command will record sample.wav as a 10 second wave file.
From,
http://linuxcommand.org/man_pages/arecord1.html
http://linux.die.net/man/1/arecord
Here, in arecord, for duration (parameter -d) only second can be used.
But for my project, I need to record for 600 milliseconds or 2700 milliseconds. Here, is there any way to use millisecond or microsecond?
Do I need to modify ALSA code to achieve this?

You need to change arecord's source code (aplay.c in the alsa-utils package) to change the type and the parsing of the timelimit variable.

You can use the code i made. It's a C program to use alsa simply.
https://github.com/Waxo/ALSA_encapsulation

With ffmpeg, here to record a 5ms wav sample:
ffmpeg -y -loglevel panic -f alsa -ac 1 -ar 44100 -i hw:2 -t 0.05 volt.wav
The sound card list for the -i parameter:
arecord -l
Bonus! To analyse the sample peaks:
sox -S volt.wav -n stats

You can compile and use the ALSACaptureSplitter application, specifying the duration as a floating point number - which will allow you to specify any accuracy you want. For example :
ALSACaptureSplitter -t 0.6 /tmp/test wav
This command will save audio 600 ms of audio to individual files in the /tmp directory.
You can build the application for your system using this email as a guide.
Here is the help output from the ALSACaptureSplitter command :
ALSACaptureSplitter -h
ALSACaptureSplitter : An application to capture input and save to independent files.
Usage:
ALSACaptureSplitter [options] outFileNamePrefix ext
e.g. ALSACaptureSplitter [options] /tmp/out wav
-D : The name of the device : (-D hw:0)
-c : The number of channels to open, if the available number is less, then it is reduced to the available : (-c 2)
-t : The duration to sample for : (-t 2.1)
-r : The sample rate to use in Hz : (-r 48000)
AUDIO FILE FORMATS:The known output file extensions (output file formats) are the following :
8svx aif aifc aiff aiffc al amb amr-nb amr-wb anb au avr awb caf cdda cdr cvs cvsd cvu dat dvms f32 f4 f64 f8 fap flac fssd gsm gsrt hcom htk ima ircam la lpc lpc10 lu mat mat4 mat5 maud mp2 mp3 nist ogg paf prc pvf raw s1 s16 s2 s24 s3 s32 s4 s8 sb sd2 sds sf sl sln smp snd sndfile sndr sndt sou sox sph sw txw u1 u16 u2 u24 u3 u32 u4 u8 ub ul uw vms voc vorbis vox w64 wav wavpcm wv wve xa xi

Related

Can I force arecord to record with a certain sampling rate if my sound card allows it?

I am using arecord to record audio using a USB microphone that allows recording up to 384k sampling rate. With Audacity I can easily record with other lower sampling rates (48k, 44.1k ..) but when I use:
arecord -vD hw:4,0 -f S16_LE -d 120 -r 48000 -c 1 sample.wav
It displays a warning message:
Warning: rate is not accurate (requested = 48000Hz, got = 384000Hz)
And records with 384000Hz.
I can't get to fix this.

Piping LAME and SOX togteher in a shell script. Is it possible?

I'm using the following in a shell script :
##For ease of understanding I'll declare the $1 variable here even though it's actually arriving remotely via an ssh2_exec command.
$1="my.mp3"
lame --decode /root/incoming/shows/$1 - | /root/incoming/stereo_tool_cmd_64 - - -s /usr/incoming/settings/setting.sts | lame -b 128 - /root/incoming/processing/$1;
So what is happening? LAME decodes the mp3 file to wav, then it is piped to STEREO TOOL (audio processing script), then back to LAME where it's re-encoded as an mp3 file and the result is written to a different directory.
This all works great but I want to use SOX during this pipe to remove all silence from the start and end of the file, while it's in it's decoded wav state, before hitting STEREO TOOL.
I've tried this but it doesn't work (SOX breaks the pipe) :
lame --decode /root/incoming/shows/$1 - | sox silence 1 0.1 0.1% reverse silence 1 0.1 0.1% reverse | /root/incoming/stereo_tool_cmd_64 - - -s /usr/incoming/settings/setting.sts | lame -b 128 - /root/incoming/processing/$1;
I know the standard way to use SOX would be :
sox input.wav output.wav silence 1 0.1 0.1% reverse silence 1 0.1 0.1% reverse;
But I can't declare the wav file here as it's being created on the fly by LAME.
Is what I'm trying to do impossible or is there a solution that will allow me to do this?

Recording each channel using ALSA API

I'm using a playstation eye, plugged into a raspberry pi. I have the raspberry pi recognising the built in microphone array of the PSEye and I can sample input levels using
arecord -vv /dev/null -r 16000 -f S16_LE -c 4 -D iec958:CARD=CameraB409241,DEV=0 /dev/null < /dev/null
Now obviously this shows the levels for all 4 channels being summed together. What I wish to do is record each channel separately. Is this possible using the ALSA API?
I've looked through this http://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html
And took a look at this http://www.linuxjournal.com/article/6735?page=0,2
But neither seemed to what I needed. This is also similar to sampling both channels of a stereo mic over ALSA as well I suppose. Eventually I want to be able to sample the dB from each microphone at a specific point in time.
To read into a separate buffer for each channel, replace SND_PCM_ACCESS_RW_INTERLEAVED with SND_PCM_ACCESS_RW_NONINTERLEAVED, and replace snd_pcm_readi with snd_pcm_readn.
If you want to record each channel to independent audio files, then you can use this application :
https://github.com/flatmax/gtkiostream/blob/master/applications/ALSACaptureSplitter.C
It needs to be compiled, which is described here :
https://lists.audioinjector.net/pipermail/people/2020-March/000028.html
To use the application specify the base file name and the extension, for example :
ALSACaptureSplitter /tmp/test wav
It can record to many different audio file formats.
You can use the options to change the device, specify the recording time, channel count, etc. Here is the help printed out by the application :
./applications/ALSACaptureSplitter -h
ALSACaptureSplitter : An application to capture input and save to
independent files.
Usage:
ALSACaptureSplitter [options] outFileNamePrefix ext
e.g. ALSACaptureSplitter [options] /tmp/out wav
-D : The name of the device : (-D hw:0)
-c : The number of channels to open, if the available number is less, then it is reduced to the available : (-c 2)
-t : The duration to sample for : (-t 2.1)
-r : The sample rate to use in Hz : (-r 48000)
AUDIO FILE FORMATS:The known output file extensions (output file formats) are the following :
8svx aif aifc aiff aiffc al amb amr-nb amr-wb anb au avr awb caf cdda cdr cvs cvsd cvu dat dvms f32 f4 f64 f8 fap flac fssd gsm gsrt hcom htk ima ircam la lpc lpc10 lu mat mat4 mat5 maud mp2 mp3 nist ogg paf prc pvf raw s1 s16 s2 s24 s3 s32 s4 s8 sb sd2 sds sf sl sln smp snd sndfile sndr sndt sou sox sph sw txw u1 u16 u2 u24 u3 u32 u4 u8 ub ul uw vms voc vorbis vox w64 wav wavpcm wv wve xa xi

How do I get an audio file sample rate using sox?

I would like to get the sample-rate of a given audio file using sox. Couldn't find the commandline to do that.
just use:
soxi <filename>
or
sox --i <filename>
to produce output such as:
Input File : 'final.flac'
Channels : 4
Sample Rate : 44100
Precision : 16-bit
Duration : 00:00:11.48 = 506179 samples = 860.849 CDDA sectors
File Size : 2.44M
Bit Rate : 1.70M
Sample Encoding: 16-bit FLAC
Comment : 'Comment=Processed by SoX'
The latter one is in case you're using the win32 version that doesn't include soxi, by default. To grab the sample rate only, just use:
soxi -r <filename>
or
sox --i -r <filename>
which will return the sample rate alone.

How to join webcam FLVs

I want my website to join some webcam recordings in FLV files (like this one). This needs to be done on Linux without user input. How do I do this? For simplicity's sake, I'll use the same flv as both inputs in hope of getting a flv that plays the same thing twice in a row.
That should be easy enough, right? There's even a full code example in the ffmpeg FAQ.
Well, pipes seem to be giving me problems (both on my mac running Leopard and on Ubuntu 8.04) so let's keep it simple and use normal files. Also, if I don't specify a rate of 15 fps, the visual part plays extremely fast. The example script thus becomes:
ffmpeg -i input.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 \
- > temp.a < /dev/null
ffmpeg -i input.flv -an -f yuv4mpegpipe - > temp.v < /dev/null
cat temp.v temp.v > all.v
cat temp.a temp.a > all.a
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
-f yuv4mpegpipe -i all.v -sameq -y output.flv
Well, using this will work for the audio, but I only get the video the first time around. This seems to be the case for any flv I throw as input.flv, including the movie teasers that come with red5.
a) Why doesn't the example script work as advertised, in particular why do I not get all the video I'm expecting?
b) Why do I have to specify a framerate while Wimpy player can play the flv at the right speed?
The only way I found to join two flvs was to use mencoder. Problem is, mencoder doesn't seem to join flvs:
mencoder input.flv input.flv -o output.flv -of lavf -oac copy \
-ovc lavc -lavcopts vcodec=flv
I get a Floating point exception...
MEncoder 1.0rc2-4.0.1 (C) 2000-2007 MPlayer Team
CPU: Intel(R) Xeon(R) CPU 5150 # 2.66GHz (Family: 6, Model: 15, Stepping: 6)
CPUflags: Type: 6 MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1
Compiled for x86 CPU with extensions: MMX MMX2 SSE SSE2
success: format: 0 data: 0x0 - 0x45b2f
libavformat file format detected.
[flv # 0x697160]Unsupported audio codec (6)
[flv # 0x697160]Could not find codec parameters (Audio: 0x0006, 22050 Hz, mono)
[lavf] Video stream found, -vid 0
[lavf] Audio stream found, -aid 1
VIDEO: [FLV1] 240x180 0bpp 1000.000 fps 0.0 kbps ( 0.0 kbyte/s)
[V] filefmt:44 fourcc:0x31564C46 size:240x180 fps:1000.00 ftime:=0.0010
** MUXER_LAVF *****************************************************************
REMEMBER: MEncoder's libavformat muxing is presently broken and can generate
INCORRECT files in the presence of B frames. Moreover, due to bugs MPlayer
will play these INCORRECT files as if nothing were wrong!
*******************************************************************************
OK, exit
Opening video filter: [expand osd=1]
Expand: -1 x -1, -1 ; -1, osd: 1, aspect: 0.000000, round: 1
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
Selected video codec: [ffflv] vfm: ffmpeg (FFmpeg Flash video)
==========================================================================
audiocodec: framecopy (format=6 chans=1 rate=22050 bits=16 B/s=0 sample-0)
VDec: vo config request - 240 x 180 (preferred colorspace: Planar YV12)
VDec: using Planar YV12 as output csp (no 0)
Movie-Aspect is undefined - no prescaling applied.
videocodec: libavcodec (240x180 fourcc=31564c46 [FLV1])
VIDEO CODEC ID: 22
AUDIO CODEC ID: 10007, TAG: 0
Writing header...
[NULL # 0x67d110]codec not compatible with flv
Floating point exception
c) Is there a way for mencoder to decode and encode flvs correctly?
So the only way I've found so far to join flvs, is to use ffmpeg to go back and forth between flv and avi, and use mencoder to join the avis:
ffmpeg -i input.flv -vcodec rawvideo -acodec pcm_s16le -r 15 file.avi
mencoder -o output.avi -oac copy -ovc copy -noskip file.avi file.avi
ffmpeg -i output.avi output.flv
d) There must be a better way to achieve this... Which one?
e) Because of the problem of the framerate, though, only flvs with constant framerate (like the one I recorded through facebook) will be converted correctly to avis, but this won't work for the flvs I seem to be recording (like this one or this one). Is there a way to do this for these flvs too?
Any help would be very appreciated.
I thought it would be a nice learning exercise to rewrite it in Ruby.
It was.
Six months later and three gems later, here's the released product.
I'll still be working a bit on it, but it works.
You'll encounter a very subtle problem here because most video and audio formats (especially in ordinary containers) use "global headers," meaning at the start of the file they have a single header which specifies compression information (like width, height, etc) for the whole file. Concatting two streams will clearly fail, as it will now have two headers instead of one and the muxer may not like this. Converting to AVI probably is resolving the issue in your case because mencoder has code to concat AVIs--that code properly handles the header issue.
After posting my question on mencoder's mailing list, trying other things, I resorted to write my own tool! I started from flvtool and after some digging in the code and writing about 40 lines of code, it works, with no loss in quality (since there is no transcoding).
I'll release it asap, in the meantime anyone interested can contact me.
dont know if this will actually work but try using this command :
cat yourVideos/*.flv >> big.flv
this will probably damage meta information so after executing that command use "flvtool" (ruby script you can find it with google) to fix it.

Resources