- #1
- 612
- 229
I'm trying to play chords using /dev/audio on my linux box. The idea is, given a set of notes, I generate the audio wave created and pass it to /dev/audio (which plays it through the speakers).
The problem is it's not working. Single notes sound appropriate, but chords sound wrong. What comes out is some kind of garbled I-don't-know-what.
I believe the issue is how I'm combining the waves made by the notes. I just add them together. Am I supposed to use some other transformation?
Here is my source code (python):
The problem is it's not working. Single notes sound appropriate, but chords sound wrong. What comes out is some kind of garbled I-don't-know-what.
I believe the issue is how I'm combining the waves made by the notes. I just add them together. Am I supposed to use some other transformation?
Here is my source code (python):
Code:
import math
import random
#constants
midC = 60
midA = midC + 9
sampleRate = 8000
#returns true with probability p
def chance(p):
return random.uniform(0,1) < p
#returns the frequency of the given note
def noteFreq(note):
note -= midA
return pow(2.0, note/12.) * 440.
#converts amplitudes to a character sequence for /dev/audio
def digitize(amplitudes):
s = ""
for d in amplitudes:
d = abs(d)
if chance(d%1.): d+=1 #anti-alias
s += chr(int(min(d,255)))
return s
#Plays notes through /dev/audio
class NotePlayer:
def __init__(self, amplitude=63, dt=0.4):
self.dt = dt
self.amplitude = amplitude
self.audio = file('/dev/audio', 'wb')
self.t = 0
def __del__(self):
self.audio.close()
#play a set of notes
def playNotes(self, notes):
freqs = map(noteFreq, notes)
data = []
tf = self.t + int(self.dt*sampleRate)
#compute the wave over a time dt, from t to t-final
for i in range(self.t, tf):
x = (i+self.t)*math.pi/sampleRate #the sample time
#combine the waves to get a sample
d = 0
for f in freqs:
d += math.sin(x*f)
d *= self.amplitude
data += [d]
#play the sound
self.audio.write(digitize(data))
self.t = tf
#plays a single note
def playNote(self, note):
self.playNotes((note,))
#The actual run-time code
p = NotePlayer()
while 1==1:
p.playNotes((midC,midC+4,midC+7)) #play the major chord C-E-G
#sounds really bad
#ctrl+c to kill
Last edited: