> On 2009-12-24, des...@verizon.net <des...@verizon.net> wrote:
>> The Natural Philosopher <t...@invalid.invalid> writes:
>>
>>> For a debian linux system.
>>>
>>> I don't want the syntesizer bit..can take care of all that..just how
>>> to hook C or indeed any other language into making a noise come out of
>>> the speakers.
>>
>> For C:
>>
>> system("aplay sound.wav");
>
> Which of course means that sound.wav has to already exist. This would be
> pretty useless for playing, in real time, a sound that you had
> synthesised. Synthesise the sound. Write it out to a .wav file, then run
> aplay on it.
Is that a requirement?
From the aplay man page:
If filename is not specified, the standard output or input is
used. The aplay utility accepts multiple filenames.
So it looks like aplay would be happy at the receiving end of a pipe.
Ok. I downloaded two packages. Both use this to open a sound device in alsa.
if ((err = snd_pcm_open (&playback_handle,"default",
SND_PCM_STREAM_PLAYBACK, 0)) < 0)
Both compile and link correctly. One runs, the other segfaults at this
point.
I conclude they aren't linking the same libraries..
..ah. I found it. One had a later call to a library function that had
changed from accepting a value, to a pointer.
I have sounds.
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
snd_pcm_t *init_sound()
{
int rc;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val;
int dir;
snd_pcm_uframes_t frames;
/* Open PCM device for playback. */
rc = snd_pcm_open(&handle, "default",
SND_PCM_STREAM_PLAYBACK, 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);
/* Two channels (stereo) */
snd_pcm_hw_params_set_channels(handle, params, 2);
/* 44100 bits/second sampling rate (CD quality) */
val = (SAMPLE_FREQ);
snd_pcm_hw_params_set_rate_near(handle, params,
&val, &dir);
/* Set period size to 1 frames. */
frames = 100000;
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);
/* We want to loop for 5 seconds */
snd_pcm_hw_params_get_period_time(params,&val, &dir);
return(handle);
}
To write a stereo pair of identical short words to it
short value;
int stereo;
stereo=(value<<16) +value;
snd_pcm_writei(handle, &stereo,1);
This works in a loop. I.e. if value is set to e.g. the integer of sine
(loop counter) you get a tone out.
Perhaps I should have said I wanted a quick'n'dirty way to make noises
for a possible sound effects board using a cheap microcontroller: First
I need to develop the effect algorithms. PICS and the like do not have
enough RAM to hold massive samples or .wavs. So algorithmic generation
is what I needed.
Once the sound is good enough, its down to PIC or equivalent with
adequate processing power to generate it.
It's been a long time since I wrote 'C' in any seriousness. Boy I am rusty..