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(&params);    /* 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

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -