summaryrefslogtreecommitdiffstats
path: root/Mac/Demo/sound
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1995-01-30 11:53:55 (GMT)
committerGuido van Rossum <guido@python.org>1995-01-30 11:53:55 (GMT)
commit17448e24081eb713ac00d7bcb681f4f0d8abfcbf (patch)
tree4f9d6768ef326173e1141b1a92af63247a42b13a /Mac/Demo/sound
parent80ffd6683ca7b06ed743c629459b06b07defbfb3 (diff)
downloadcpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.zip
cpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.tar.gz
cpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.tar.bz2
Committed a more or less working version.
Diffstat (limited to 'Mac/Demo/sound')
-rw-r--r--Mac/Demo/sound/morse.py180
-rw-r--r--Mac/Demo/sound/playaiff.py45
2 files changed, 225 insertions, 0 deletions
diff --git a/Mac/Demo/sound/morse.py b/Mac/Demo/sound/morse.py
new file mode 100644
index 0000000..bf5fa5f
--- /dev/null
+++ b/Mac/Demo/sound/morse.py
@@ -0,0 +1,180 @@
+import sys, math, audiodev
+
+DOT = 30
+DAH = 80
+OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
+SAMPWIDTH = 2
+FRAMERATE = 44100
+BASEFREQ = 441
+QSIZE = 20000
+
+morsetab = {
+ 'A': '.-', 'a': '.-',
+ 'B': '-...', 'b': '-...',
+ 'C': '-.-.', 'c': '-.-.',
+ 'D': '-..', 'd': '-..',
+ 'E': '.', 'e': '.',
+ 'F': '..-.', 'f': '..-.',
+ 'G': '--.', 'g': '--.',
+ 'H': '....', 'h': '....',
+ 'I': '..', 'i': '..',
+ 'J': '.---', 'j': '.---',
+ 'K': '-.-', 'k': '-.-',
+ 'L': '.-..', 'l': '.-..',
+ 'M': '--', 'm': '--',
+ 'N': '-.', 'n': '-.',
+ 'O': '---', 'o': '---',
+ 'P': '.--.', 'p': '.--.',
+ 'Q': '--.-', 'q': '--.-',
+ 'R': '.-.', 'r': '.-.',
+ 'S': '...', 's': '...',
+ 'T': '-', 't': '-',
+ 'U': '..-', 'u': '..-',
+ 'V': '...-', 'v': '...-',
+ 'W': '.--', 'w': '.--',
+ 'X': '-..-', 'x': '-..-',
+ 'Y': '-.--', 'y': '-.--',
+ 'Z': '--..', 'z': '--..',
+ '0': '-----',
+ '1': '.----',
+ '2': '..---',
+ '3': '...--',
+ '4': '....-',
+ '5': '.....',
+ '6': '-....',
+ '7': '--...',
+ '8': '---..',
+ '9': '----.',
+ ',': '--..--',
+ '.': '.-.-.-',
+ '?': '..--..',
+ ';': '-.-.-.',
+ ':': '---...',
+ "'": '.----.',
+ '-': '-....-',
+ '/': '-..-.',
+ '(': '-.--.-',
+ ')': '-.--.-',
+ '_': '..--.-',
+ ' ': ' '
+}
+
+# If we play at 44.1 kHz (which we do), then if we produce one sine
+# wave in 100 samples, we get a tone of 441 Hz. If we produce two
+# sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
+# appears to be a nice one for playing morse code.
+def mkwave(octave):
+ global sinewave, nowave
+ sinewave = ''
+ n = int(FRAMERATE / BASEFREQ)
+ for i in range(n):
+ val = int(math.sin(2 * math.pi * i * octave / n) * 0x7fff)
+ sample = chr((val >> 8) & 255) + chr(val & 255)
+ sinewave = sinewave + sample[:SAMPWIDTH]
+ nowave = '\0' * (n*SAMPWIDTH)
+
+mkwave(OCTAVE)
+
+class BufferedAudioDev:
+ def __init__(self, *args):
+ import audiodev
+ self._base = apply(audiodev.AudioDev, args)
+ self._buffer = []
+ self._filled = 0
+ self._addmethods(self._base, self._base.__class__)
+ def _addmethods(self, inst, cls):
+ for name in cls.__dict__.keys():
+ if not hasattr(self, name):
+ try:
+ setattr(self, name, getattr(inst, name))
+ except:
+ pass
+ for basecls in cls.__bases__:
+ self._addmethods(self, inst, basecls)
+ def writeframesraw(self, frames):
+ self._buffer.append(frames)
+ self._filled = self._filled + len(frames)
+ if self._filled >= QSIZE:
+ self.flush()
+ def wait(self):
+ self.flush()
+ self._base.wait()
+ def flush(self):
+ print 'flush: %d blocks, %d bytes' % (len(self._buffer), self._filled)
+ if self._buffer:
+ import string
+ self._base.writeframes(string.joinfields(self._buffer, ''))
+ self._buffer = []
+ self._filled = 0
+
+def main(args = sys.argv[1:]):
+ import getopt, string
+ try:
+ opts, args = getopt.getopt(args, 'o:p:')
+ except getopt.error:
+ sys.stderr.write('Usage ' + sys.argv[0] +
+ ' [ -o outfile ] [ args ] ...\n')
+ sys.exit(1)
+ dev = None
+ for o, a in opts:
+ if o == '-o':
+ import aifc
+ dev = aifc.open(a, 'w')
+ dev.setframerate(FRAMERATE)
+ dev.setsampwidth(SAMPWIDTH)
+ dev.setnchannels(1)
+ if o == '-p':
+ mkwave(string.atoi(a))
+ if not dev:
+ dev = BufferedAudioDev()
+ dev.setoutrate(FRAMERATE)
+ dev.setsampwidth(SAMPWIDTH)
+ dev.setnchannels(1)
+ dev.close = dev.stop
+ if args:
+ line = string.join(args)
+ else:
+ line = sys.stdin.readline()
+ while line:
+ print line
+ mline = morse(line)
+ print mline
+ play(mline, dev)
+ if hasattr(dev, 'wait'):
+ dev.wait()
+ if not args:
+ line = sys.stdin.readline()
+ else:
+ line = ''
+ dev.close()
+
+# Convert a string to morse code with \001 between the characters in
+# the string.
+def morse(line):
+ res = ''
+ for c in line:
+ try:
+ res = res + morsetab[c] + '\001'
+ except KeyError:
+ pass
+ return res
+
+# Play a line of morse code.
+def play(line, dev):
+ for c in line:
+ if c == '.':
+ sine(dev, DOT)
+ elif c == '-':
+ sine(dev, DAH)
+ else:
+ pause(dev, DAH)
+ pause(dev, DOT)
+
+def sine(dev, length):
+ dev.writeframesraw(sinewave*length)
+
+def pause(dev, length):
+ dev.writeframesraw(nowave*length)
+
+if __name__ == '__main__' or sys.argv[0] == __name__:
+ main()
diff --git a/Mac/Demo/sound/playaiff.py b/Mac/Demo/sound/playaiff.py
new file mode 100644
index 0000000..1022fc8
--- /dev/null
+++ b/Mac/Demo/sound/playaiff.py
@@ -0,0 +1,45 @@
+from Sound import *
+import Snd
+
+import aifc, audioop
+
+fn = 'f:just samples:2ndbeat.aif'
+af = aifc.open(fn, 'r')
+print af.getparams()
+print 'nframes =', af.getnframes()
+print 'nchannels =', af.getnchannels()
+print 'framerate =', af.getframerate()
+nframes = min(af.getnframes(), 100000)
+frames = af.readframes(nframes)
+print 'len(frames) =', len(frames)
+print repr(frames[:100])
+frames = audioop.add(frames, '\x80'*len(frames), 1)
+print repr(frames[:100])
+
+import struct
+
+header1 = struct.pack('llhhllbbl',
+ 0,
+ af.getnchannels(),
+ af.getframerate(),0,
+ 0,
+ 0,
+ 0xFF,
+ 60,
+ nframes)
+print repr(header1)
+header2 = struct.pack('llhlll', 0, 0, 0, 0, 0, 0)
+header3 = struct.pack('hhlll',
+ af.getsampwidth()*8,
+ 0,
+ 0,
+ 0,
+ 0)
+print repr(header3)
+header = header1 + header2 + header3
+
+buffer = header + frames
+
+chan = Snd.SndNewChannel(5,0x00C0)
+
+Snd.SndDoCommand(chan, (bufferCmd, 0, buffer), 0)