Come scrivere file WAV stereo in Python?
Domanda
Il codice seguente scrive una semplice sinusoidale alla frequenza di 400Hz in un file WAV mono. Come deve questo codice essere modificato al fine di produrre un stereo file WAV. Il secondo canale dovrebbe essere in una frequenza differente.
import math
import wave
import struct
freq = 440.0
data_size = 40000
fname = "WaveTest.wav"
frate = 11025.0 # framerate as a float
amp = 64000.0 # multiplier for amplitude
sine_list_x = []
for x in range(data_size):
sine_list_x.append(math.sin(2*math.pi*freq*(x/frate)))
wav_file = wave.open(fname, "w")
nchannels = 1
sampwidth = 2
framerate = int(frate)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
wav_file.setparams((nchannels, sampwidth, framerate, nframes,
comptype, compname))
for s in sine_list_x:
# write the audio frames to file
wav_file.writeframes(struct.pack('h', int(s*amp/2)))
wav_file.close()
Soluzione
Crea un elenco parallelo sine_list_y
con l'altra frequenza / canale, set nchannels=2
, e nel circuito di uscita uso for s, t in zip(sine_list_x, sine_list_y):
la clausola di intestazione e un corpo con due chiamate writeframes
- uno per s
, uno per t
. IOW, cornici corrispondenti per i due canali "alternativi" nel file.
Vedere per esempio questa pagina per una descrizione completa di tutti i possibili formati di file WAV, e cito:
campioni audio digitale multicanale sono memorizzati come dati onda interlacciato che significa semplicemente che l'audio campioni di un multi-canale (ad esempio stereo e surround) file wave sono memorizzati dal bicicletta attraverso l'audio campioni per ciascun canale prima avanzare al tempo campione successivo. Questo viene fatto in modo che i file audio può essere giocato o in streaming prima della intero file può essere letto. Questo è utile quando si riproduce un file di grandi dimensioni da disco (Che non può completamente adattarsi memoria) o lo streaming di un file sul Internet. I valori nel diagramma di seguito saranno memorizzati in un file Wave nell'ordine in cui sono elencati nella colonna Value (dall'alto in basso).
e la seguente tabella mostra chiaramente i campioni dei canali che vanno a sinistra, destra, sinistra, destra, ...
Altri suggerimenti
Per un esempio che produce un file .wav
stereo, vedere la test_wave.py
modulo .
Il test produce un file all-zero.
È possibile modificare con l'inserimento di valori campione alternata.
nchannels = 2
sampwidth = 2
framerate = 8000
nframes = 100
# ...
def test_it(self):
self.f = wave.open(TESTFN, 'wb')
self.f.setnchannels(nchannels)
self.f.setsampwidth(sampwidth)
self.f.setframerate(framerate)
self.f.setnframes(nframes)
output = '\0' * nframes * nchannels * sampwidth
self.f.writeframes(output)
self.f.close()