如何从内存播放WAV数据?
我现在正在做一个声音实验,遇到了一个问题。我把一组波形数据保存到一个 .wav 文件里,然后播放它。但是,有没有办法跳过这个步骤,直接从内存中播放声音呢?我希望这个解决方案能在不同的平台上都能用。
2 个回答
1
在内存中生成正弦波样本并创建一个wav文件,然后在Windows上播放它:
import math
import struct
import wave
import winsound
import cStringIO as StringIO
num_channels = 2
num_bytes_per_sample = 2
sample_rate_hz = 44100
sound_length_sec = 2.0
sound_freq_hz = 500
memory_file = StringIO.StringIO()
wave_file = wave.open(memory_file, 'w')
wave_file.setparams((num_channels, num_bytes_per_sample, sample_rate_hz, 0, 'NONE', 'not compressed'))
num_samples_per_channel = int(sample_rate_hz * sound_length_sec)
freq_pos = 0.0
freq_step = 2 * math.pi * sound_freq_hz / sample_rate_hz
sample_list = []
for i in range(num_samples_per_channel):
sample = math.sin(freq_pos) * 32767
sample_packed = struct.pack('h', sample)
for j in range(num_channels):
sample_list.append(sample_packed)
freq_pos += freq_step
sample_str = ''.join(sample_list)
wave_file.writeframes(sample_str)
wave_file.close()
winsound.PlaySound(memory_file.getvalue(), winsound.SND_MEMORY)
memory_file.close()
3
我猜你是在使用wave库,对吧?
文档上说:
wave.open(file[, mode])
如果file是一个字符串,就用这个名字打开文件;如果不是,就把它当作一个可以查找的文件对象。
这意味着你应该能做类似这样的事情:
>>> import wave
>>> from StringIO import StringIO
>>> file_on_disk = open('myfile.wav', 'rb')
>>> file_in_memory = StringIO(file_on_disk.read())
>>> file_on_disk.seek(0)
>>> file_in_memory.seek(0)
>>> file_on_disk.read() == file_in_memory.read()
True
>>> wave.open(file_in_memory, 'rb')
<wave.Wave_read instance at 0x1d6ab00>
补充说明(见评论):以防你的问题不仅仅是从内存中读取文件,而是想要在Python中播放它...
一个选择是使用pymedia
import time, wave, pymedia.audio.sound as sound
f= wave.open( 'YOUR FILE NAME', 'rb' ) # ← you can use StrinIO here!
sampleRate= f.getframerate()
channels= f.getnchannels()
format= sound.AFMT_S16_LE
snd= sound.Output( sampleRate, channels, format )
s= f.readframes( 300000 )
snd.play( s )
while snd.isPlaying(): time.sleep( 0.05 )
[来源:pymedia教程(为了简洁,我省略了他们的解释性评论)]