import wave import numpy as np import scipy.signal as sig import math # Nombre d’octets par échantillon samp_width = 2 # Valeur maximale d’un échantillon max_val = 2 ** (8 * samp_width - 1) - 1 # Fréquence d’échantillonnage (Hertz) samp_rate = 44100 def add_signal(dest, start, source): dest[int(samp_rate * start):int(samp_rate * start) + len(source)] += source def silence(dur): return np.zeros((int(samp_rate * dur),)) def sine(dur, freq, value=1): x = np.arange(int(samp_rate * dur)) return value * max_val * np.sin(2 * np.pi * freq * x / samp_rate) def square(dur, freq, value=1): x = np.arange(int(samp_rate * dur)) return value * max_val * sig.square(2 * np.pi * freq * x / samp_rate) def envelope(attack, decay, release, signal): total = len(signal) attack = int(attack * total) decay = int(decay * total) release = int(release * total) sustain = total - attack - decay - release return signal * np.concatenate(( np.linspace(start=0, stop=1, num=attack, endpoint=False), np.linspace(start=1, stop=2/3, num=decay, endpoint=False), np.linspace(start=2/3, stop=2/3, num=sustain, endpoint=False), np.linspace(start=2/3, stop=0, num=release, endpoint=True), )) notes = { 'do': 0, 'si#': 0, 'do#': 1, 'reb': 1, 're': 2, 're#': 3, 'mib': 3, 'mi': 4, 'fab': 4, 'fa': 5, 'mi#': 5, 'fa#': 6, 'solb': 6, 'sol': 7, 'sol#': 8, 'lab': 8, 'la': 9, 'la#': 10, 'sib': 10, 'si': 11, 'dob': 11, } def note_freq(note, octave): return (440 * (2 ** (octave - 3)) * math.pow(2, (notes[note] - 9) / 12)) def note_freqs(notes): return list(map(lambda info: note_freq(*info), notes)) def chord(instr, dur, freqs, value=1): signal = np.zeros((int(samp_rate * dur),)) for freq in freqs: signal += instr(dur, freq, value / len(freqs)) return signal def save_signal(out_name, signal): with wave.open(out_name, 'w') as file: file.setnchannels(1) file.setsampwidth(samp_width) file.setframerate(samp_rate) file.writeframesraw(signal.astype('