c - How to record sound in buffer using ALSA -
i'm begining learn linux , alsa , wondering if there way store sound record microphone directly buffer. read here http://www.linuxjournal.com/article/6735?page=0,2 how make recording program. need little more complex. need record sound untill hit key. reason need because i'm messing raspberrypi(debian on it) , see if turn sound monitoring/detecting device.
my main problem when try use record (./rec >name.raw ) nothing. ouputs empty .raw file.
#define alsa_pcm_new_hw_params_api #include <termios.h> #include <alsa/asoundlib.h> struct termios stdin_orig; // structure save parameters void term_reset() { tcsetattr(stdin_fileno,tcsanow,&stdin_orig); tcsetattr(stdin_fileno,tcsaflush,&stdin_orig); } void term_nonblocking() { struct termios newt; tcgetattr(stdin_fileno, &stdin_orig); fcntl(stdin_fileno, f_setfl, o_nonblock); // non-blocking newt = stdin_orig; newt.c_lflag &= ~(icanon | echo); tcsetattr(stdin_fileno, tcsanow, &newt); atexit(term_reset); } int main() { int key=0; long loops; int rc; int size; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; int dir; snd_pcm_uframes_t frames; char *buffer; /* open pcm device recording (capture). */ rc = snd_pcm_open(&handle, "default", snd_pcm_stream_capture, 0); if (rc < 0) { fprintf(stderr, "unable open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* allocate hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* fill in default values. */ snd_pcm_hw_params_any(handle, params); /* set desired hardware parameters. */ /* interleaved mode */ snd_pcm_hw_params_set_access(handle, params, snd_pcm_access_rw_interleaved); /* signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, snd_pcm_format_s16_le); /* 1 channel (mono) */ snd_pcm_hw_params_set_channels(handle, params, 1); /* 16000 bits/second sampling rate */ val = 16000; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* set period size 2048 frames. */ frames = 2048; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* write parameters driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable set hw parameters: %s\n", snd_strerror(rc)); exit(1); } /* use buffer large enough hold 1 period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * 2; /* 2 bytes/sample, 1 channels */ buffer = (char *) malloc(size); while (key == 0) { rc = snd_pcm_readi(handle, buffer, frames); if (rc == -epipe) { /* epipe means overrun */ fprintf(stderr, "overrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error read: %s\n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short read, read %d frames\n", rc); } rc = write(1, buffer, size); if (rc != size) fprintf(stderr, "short write: wrote %d bytes\n", rc); key = getchar(); } snd_pcm_drain(handle); snd_pcm_close(handle); free(buffer); return 0; }
here how did python. tested work on desktop debian usb plantronics headphones. need install python-qt4
, python-pyaudio
packages work.
also, you'll need set input device microphone. in gnome switched both input , output devices via system tools -> system settings
-> sound
. if have raspbian
, not debian
on raspberry, do, it's gonna tougher, cause there's lxde instead of gnome. can use alsamixer
, f6 button there set audio cards, problem alsa low-level interface, while most linuxes use sound server on top of it, such pulseaudio or jack. you'll need luck/spent time make sure switched input/output device mic/headphones.
if use jack microphone, plugged in through jack input of raspberry pi, note raspberry's jack input only, won't able play recordings , need usb headphones listen wav.
personally, feel alsa poorly documented (i suppose it's intentional job security) , don't deal it.
import pyaudio import wave import sys pyqt4.qtcore import * pyqt4.qtgui import * # qt part: create window, has "stop" flag. # stop flag defaults false, set true, when press key. # value of flag checked in main loop , loop exits when flag true. app = qapplication(sys.argv) class mywindow(qwidget): def __init__(self): super(qwidget, self).__init__() self.stop = false def keypressevent(self, event): print "keypressedevent caught!" self.stop = true window = mywindow() window.show() # sound processing part: create input stream read microphone. p = pyaudio.pyaudio() stream = p.open(format = p.get_format_from_width(2), channels = 2, rate=44100, input=true, output=false, frames_per_buffer=1024) # main loop: iteratively poll audio , gui: audio data stored in output_buffer, # whereas gui checked stop flag value (if keypressedevent happened, flag set # true , break our main loop). output_buffer = "" while true: app.processevents() data = stream.read(1024) output_buffer += data if window.stop: break stream.stop_stream() stream.close() # here output contents of output_buffer .wav file output_wav = wave.open("output.wav", 'w') output_wav.setparams((2, 2, 44100, len(output_buffer),"none","not compressed")) output_wav.writeframesraw(output_buffer) p.terminate()
Comments
Post a Comment