05-23-06 06:17 AM
Miko wrote:
> Does anyone know a good document on how I could
> write a c program that plays a tune by writing to
> /dev/dsp? By that I mean that the tune should be
> generated in the program
As far as I know, /dev/dsp can be set (probably with some
ioctl() or something) to be simply a linear PCM device.
In that case, the writing to /dev/dsp part is pretty simple,
and the difficulty is getting the right samples to write.
The simplest thing to do is to start with a square wave.
If you have a 44.1 kHz sampling rate and you want to play
a 441 Hz tone, all you have to do is pick two values in
the range (the range being -32768 to +32767 if you use signed
16-bit integer samples), like maybe -5000 and +5000, and play
one for 50 samples, then the other for 50 samples, then back
to the first. That way, you repeat after 100 samples, which
means you repeat 441 times a second when using a 44100 Hz
sampling rate.
Having said that, you probably want to get a little more
sophisticated at some point and change to a note at a
different pitch. If you want to fit in with Western music,
you'll probably want to stick with the 12-tone scale. That's
pretty easy to handle since in a standard scale (equal
temperament), the notes are each related by the ratio 2^(1/12).
So, if you have a 440 Hz tone (an A), then an A# (or B-flat)
is 440 * 2^(1/12) Hz, or about 466.1637 Hz. As you can see,
you're likely going to get into floating point if you intend
to keep the pitches accurate. You'll notice that one nice
property of the relative pitches of notes is that a note one
octave above another in the 12-tone scale would be a ratio of
2^(12/12), which reduces to 2, i.e. double. So the note an
octave above 440 Hz is 880 Hz.
That should be enough to get you going. A nice simple first
project would be a program that reads a data file and plays
notes according to what's in the data file. The data file
could simply be a text file where each line contains a frequency
in Hz and a duration in milliseconds. You could play a square
wave at that frequency for the recommended duration. By
hand-crafting the file, it would be fairly straightforward
to have the system play a recognizable tune.
The next step is polyphony (i.e. playing more than one note
at a time). This is a bit tougher. Basically, you need to
generate multiple waves and then mix them together. Luckily,
mixing waves together is as simple as adding them. The only
caveat is that you need to make sure that when you add all
your waves together, you don't overflow the 16-bit integers.
If you do, it will sound awful. :-)
- Logan
[ Post a follow-up to this message ]
|