2010-09-03 9 views
10

Il seguente codice scrive un semplice seno a frequenza 400Hz in un file WAV mono. Come dovrebbe essere modificato questo codice per produrre un file WAV stereo. Il secondo canale dovrebbe avere una frequenza diversa.Come scrivere file wav stereo in Python?

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() 
+1

Set 'nchannels = 2' per un inizio;) – ChrisF

risposta

9

torso un parallelo lista sine_list_y con l'altra frequenza/canale, impostare nchannels=2, e nell'uso loop di uscita for s, t in zip(sine_list_x, sine_list_y): la clausola di intestazione e un corpo con due writeframes chiamate - uno per s, una per t . IOW, i frame corrispondenti per i due canali "si alternano" nel file.

Vedere ad es. this pagina per una descrizione approfondita di tutti i possibili formati di file WAV, e cito: campioni audio digitali

multicanale vengono memorizzati come dati onda interlacciati che significa semplicemente che l'audio campioni di un multi-canale (come il file d'onda stereo e surround) sono memorizzati ciclicamente attraverso i campioni audio per ciascun canale prima dello che passa al tempo di campionamento successivo. Questo è fatto in modo che i file audio possano essere riprodotti o trasmessi in streaming prima che sia possibile leggere l'intero file . È utile durante la riproduzione di un file di grandi dimensioni dal disco (che potrebbe non adattarsi completamente alla memoria ) o allo streaming di un file tramite la rete . I valori nello schema di seguito sono memorizzati in un file Wave nell'ordine in cui sono elencati nella colonna Valore (dall'alto in basso).

e la seguente tabella mostra chiaramente i campioni dei canali andando a sinistra, destra, sinistra, destra, ...

+5

Io personalmente vederli andare ↑ ↑ ↓ ↓ ← → ← → B A, ma che potrebbe essere solo me. –

3

Per un esempio che produce un file stereo .wav, vedere la test_wave.py module. Il test produce un file tutto-zero. È possibile modificare inserendo valori campione alternati.

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()