python tkinter create audio sine wave in l 26 r

Solutions on MaxInterview for python tkinter create audio sine wave in l 26 r by the best coders in the world

showing results for - "python tkinter create audio sine wave in l 26 r"
Aubrey
26 May 2016
1#!/usr/bin/env python
2import sys
3import wave
4import math
5import struct
6import random
7import argparse
8from itertools import *
9
10def grouper(n, iterable, fillvalue=None):
11    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
12    args = [iter(iterable)] * n
13    return izip_longest(fillvalue=fillvalue, *args)
14
15def sine_wave(frequency=440.0, framerate=44100, amplitude=0.5):
16    '''
17    Generate a sine wave at a given frequency of infinite length.
18    '''
19    period = int(framerate / frequency)
20    if amplitude > 1.0: amplitude = 1.0
21    if amplitude < 0.0: amplitude = 0.0
22    lookup_table = [float(amplitude) * math.sin(2.0*math.pi*float(frequency)*(float(i%period)/float(framerate))) for i in xrange(period)]
23    return (lookup_table[i%period] for i in count(0))
24
25def square_wave(frequency=440.0, framerate=44100, amplitude=0.5):
26    for s in sine_wave(frequency, framerate, amplitude):
27        if s > 0:
28            yield amplitude
29        elif s < 0:
30            yield -amplitude
31        else:
32            yield 0.0
33
34def damped_wave(frequency=440.0, framerate=44100, amplitude=0.5, length=44100):
35    if amplitude > 1.0: amplitude = 1.0
36    if amplitude < 0.0: amplitude = 0.0
37    return (math.exp(-(float(i%length)/float(framerate))) * s for i, s in enumerate(sine_wave(frequency, framerate, amplitude)))
38
39def white_noise(amplitude=0.5):
40    '''
41    Generate random samples.
42    '''
43    return (float(amplitude) * random.uniform(-1, 1) for i in count(0))
44
45def compute_samples(channels, nsamples=None):
46    '''
47    create a generator which computes the samples.
48
49    essentially it creates a sequence of the sum of each function in the channel
50    at each sample in the file for each channel.
51    '''
52    return islice(izip(*(imap(sum, izip(*channel)) for channel in channels)), nsamples)
53
54def write_wavefile(filename, samples, nframes=None, nchannels=2, sampwidth=2, framerate=44100, bufsize=2048):
55    "Write samples to a wavefile."
56    if nframes is None:
57        nframes = -1
58
59    w = wave.open(filename, 'w')
60    w.setparams((nchannels, sampwidth, framerate, nframes, 'NONE', 'not compressed'))
61
62    max_amplitude = float(int((2 ** (sampwidth * 8)) / 2) - 1)
63
64    # split the samples into chunks (to reduce memory consumption and improve performance)
65    for chunk in grouper(bufsize, samples):
66        frames = ''.join(''.join(struct.pack('h', int(max_amplitude * sample)) for sample in channels) for channels in chunk if channels is not None)
67        w.writeframesraw(frames)
68
69    w.close()
70
71    return filename
72
73def write_pcm(f, samples, sampwidth=2, framerate=44100, bufsize=2048):
74    "Write samples as raw PCM data."
75    max_amplitude = float(int((2 ** (sampwidth * 8)) / 2) - 1)
76
77    # split the samples into chunks (to reduce memory consumption and improve performance)
78    for chunk in grouper(bufsize, samples):
79        frames = ''.join(''.join(struct.pack('h', int(max_amplitude * sample)) for sample in channels) for channels in chunk if channels is not None)
80        f.write(frames)
81
82    f.close()
83
84    return filename
85
86def main():
87    parser = argparse.ArgumentParser()
88    parser.add_argument('-c', '--channels', help="Number of channels to produce", default=2, type=int)
89    parser.add_argument('-b', '--bits', help="Number of bits in each sample", choices=(16,), default=16, type=int)
90    parser.add_argument('-r', '--rate', help="Sample rate in Hz", default=44100, type=int)
91    parser.add_argument('-t', '--time', help="Duration of the wave in seconds.", default=60, type=int)
92    parser.add_argument('-a', '--amplitude', help="Amplitude of the wave on a scale of 0.0-1.0.", default=0.5, type=float)
93    parser.add_argument('-f', '--frequency', help="Frequency of the wave in Hz", default=440.0, type=float)
94    parser.add_argument('filename', help="The file to generate.")
95    args = parser.parse_args()
96
97    # each channel is defined by infinite functions which are added to produce a sample.
98    channels = ((sine_wave(args.frequency, args.rate, args.amplitude),) for i in range(args.channels))
99
100    # convert the channel functions into waveforms
101    samples = compute_samples(channels, args.rate * args.time)
102
103    # write the samples to a file
104    if args.filename == '-':
105        filename = sys.stdout
106    else:
107        filename = args.filename
108    write_wavefile(filename, samples, args.rate * args.time, args.channels, args.bits / 8, args.rate)
109
110if __name__ == "__main__":
111    main()