How to record sound in buffer using ALSA
-
I'm beginning to learn Linux and ALSA and I was wondering if there is a way to store the sound I record from a microphone directly to the buffer. I read here http://www.linuxjournal.com/article/6735?page=0,2 how to make my recording program. But what I need is a little more complex. I need to record sound until I hit a key. Also if it is possible to output the number of recorded frames (to a txt file or the console). The reason I need this is because I'm messing with a RaspberryPI (Debian on it) and to see if I could turn it into a sound monitoring/detecting device. #define ALSA_PCM_NEW_HW_PARAMS_API #include <alsa/asoundlib.h> int main() { 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 for recording (capture). */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the 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); /* One channel (monoo) */ 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 to 2048 frames. */ frames = 2048; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * 2; /* 2 bytes/sample, 1 channels */ buffer = (char *) malloc(size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); loops = 5000000 / val; while (loops > 0) { loops--; 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 from 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); } snd_pcm_drain(handle); snd_pcm_close(handle); free(buffer); return 0; }
-
Answer:
Here is how I did that with python. Tested to work on my desktop Debian with USB Plantronics headphones. You need to install python-qt4 and python-pyaudio packages for this to work. Also, you'll need to set your input device to microphone. In GNOME I switched both input and output devices via System Tools -> System Settings -> Sound. If you have Raspbian, not Debian on your Raspberry, as I do, it's gonna be tougher, cause there's LXDE instead of GNOME. You can use alsamixer and F6 button there to set audio cards, but the problem is that ALSA is low-level interface, while http://tuxradar.com/content/how-it-works-linux-audio-explained, such as PulseAudio or JACK. You'll need some luck/spent time to make sure you switched input/output device to your mic/headphones. If you use Jack microphone, plugged in through Jack input of your Raspberry Pi, note that Raspberry's Jack is input only, so you won't be able to play back your recordings and need some USB headphones to listen to your wav. Personally, I feel that ALSA is very poorly documented (I suppose it's intentional https://www.thc.org/root/phun/unmaintain.html) and I don't like to deal with it. import pyaudio import wave import sys from PyQt4.QtCore import * from PyQt4.QtGui import * # This is Qt part: we create a window, which has a "stop" flag. # Stop flag defaults to False, but is set to True, when you press a key. # Value of that flag is checked in main loop and loop exits when flag is 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() # This is sound processing part: we create an input stream to read from 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) # This is main loop: we iteratively poll audio and gui: audio data are stored in output_buffer, # whereas gui is checked for stop flag value (if keyPressedEvent happened, flag will be set # to True and 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 we output contents of output_buffer as .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()
Aiurea Adica tot YO at Stack Overflow Visit the source
Related Q & A:
- How to record sound in iOS?Best solution by developer.apple.com
- How to record bluetooth headset audio?Best solution by Stack Overflow
- How to record screen with sound at the same time?Best solution by Yahoo! Answers
- Can you record your Xbox 360 using a digital camera?Best solution by support.xbox.com
- How do you record sound off the internet?Best solution by Yahoo! Answers
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.