【问题标题】:How to play WAV data right from memory?如何直接从内存中播放 WAV 数据?
【发布时间】:2012-01-01 23:48:02
【问题描述】:

我目前正在进行一项声音实验,但遇到了一个问题。我将一组波形数据保存到 .wav 文件并播放它,但有没有办法跳过这一步,直接从内存中播放声音?我正在寻找一种可以跨平台工作的解决方案。

【问题讨论】:

  • StringIO 也许?
  • 您能否澄清一下您的问题是仅从内存中加载文件(但您知道如何从 python 中播放),或者您完全不知道这两个步骤中的任何一个? [请参阅我的回答的 cmets 以了解我为什么要问! :)]

标签: python wav


【解决方案1】:

我猜你使用的是wave library,对吧?

文档说:

wave.open(file[, mode])

如果文件是一个字符串,则以该名称打开文件,否则将其视为可搜索的类文件对象。

这意味着您应该能够按照以下方式做一些事情:

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

编辑(参见 cmets):以防万一您的问题不仅是从内存中读取文件,而且完全是从 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 tutorial(为简洁起见,我省略了它们的解释性 cmets]

【讨论】:

  • 这会让你从内​​存中读取一个 WAV 文件,但它不会让你播放它。
  • 如果不清楚,StringIO 基本上允许您将内存缓冲区包装在类似文件的对象中,以处理大多数需要文件的东西。
  • @icktoofay - 确实。但我知道这是 OP 海报的问题:他可以从磁盘加载 [并播放] 一个文件,但不知道如何从内存中执行第一个位(加载)......还是我错过什么?
  • @mac:这个问题问的是如何从记忆中播放 WAV,你的答案回答了如何阅读它,而不是如何播放它。
  • @icktoofay - 我以为他已经知道怎么玩了,但是阅读您的评论后,我发现问题含糊不清……我对 OP 发表了评论。
【解决方案2】:

使用内存中生成的正弦波样本创建一个 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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多