In an attempt to study how the brain learns I wanted to a play a series of continuous beeps of different frequencies. What seemed like a 5 min hack, took me around 3 days to get working.
The following code from here would generate a sine wave at the frequency "f". Make sure that you put the alsa headers in the extern "C":
Aim: The aim of this post is to show you how to play a beep sound of a specific frequency on the Raspberry Pi.
So lets's get started!
Step 0: Prerequisite
The first step is to enable sound on the raspberry pi, follow the steps here if you haven't already tinkered around with sound. Make sure the pi plays the "front-center" sample using aplay, and that you can hear it using the 3.5 mm jack.
Step 1: Compiling the ALSA Library
The next thing to do is to download the ALSA libraries, and set them up. Use:
wget http://alsa.cybermirror.org/lib/alsa-lib-1.0.27.2.tar.bz2
to download the tarball source and extract it. Go inside the alsa-lib directory and execute:
./configure && make
then as root, execute:
sudo make install
Step 2: Link the libraries
Now we need to use the libraries in our C++ project. I assume the reader has already created a C++ project with a CMakeLists.txt file.
Modify your CMakeLists to say:
add_executable(<BinaryFile> <sourcefile.cpp>)
target_link_libraries(<BinaryFile> /usr/lib/libasound.so.2.0.0)
The following code from here would generate a sine wave at the frequency "f". Make sure that you put the alsa headers in the extern "C":
#include <alsa/asoundlib.h> #include <alsa/pcm.h> #include <math.h> #define BUFFER_LEN 48000 static char *device = "default"; //soundcard snd_output_t *output = NULL; float buffer [BUFFER_LEN]; int main(void) { int err; int j,k; int f = 440; //frequency int fs = 48000; //sampling frequency snd_pcm_t *handle; snd_pcm_sframes_t frames; // ERROR HANDLING if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("Playback open error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } if ((err = snd_pcm_set_params(handle, SND_PCM_FORMAT_FLOAT, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 48000, 1, 500000)) < 0) { printf("Playback open error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } // SINE WAVE printf("Sine tone at %dHz ",f); for (k=0; k<BUFFER_LEN; k++){ buffer[k] = (sin(2*M_PI*f/fs*k)); //sine wave value generation } for (j=0; j<5; j++){ frames = snd_pcm_writei(handle, buffer, BUFFER_LEN); //sending values to sound driver } snd_pcm_close(handle); return 0; }
That's it!
If you have any trouble feel free to contact me. It was a headache for me too :)