Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从wav文件中获取wav样本?_Python_Wav - Fatal编程技术网

Python 如何从wav文件中获取wav样本?

Python 如何从wav文件中获取wav样本?,python,wav,Python,Wav,我想知道如何从.wav文件中获取样本,以便执行两个.wav文件的窗口连接 谁能告诉我怎么做吗?你可以使用这个模块。首先,您应该阅读元数据,例如样本大小或通道数。使用readframes()方法,可以读取示例,但只能作为字节字符串读取。根据样本格式,必须使用将其转换为样本 或者,如果您想将样本作为浮点数数组,可以使用SciPy的模块。标准库的模块是关键:当然,在代码顶部导入wave之后,wave.open('the.wav','r')返回“wave read”对象,您可以使用.readframes

我想知道如何从.wav文件中获取样本,以便执行两个.wav文件的窗口连接

谁能告诉我怎么做吗?

你可以使用这个模块。首先,您应该阅读元数据,例如样本大小或通道数。使用
readframes()
方法,可以读取示例,但只能作为字节字符串读取。根据样本格式,必须使用将其转换为样本

或者,如果您想将样本作为浮点数数组,可以使用SciPy的模块。

标准库的模块是关键:当然,在代码顶部导入wave之后,
wave.open('the.wav','r')
返回“wave read”对象,您可以使用
.readframes
方法从中读取帧,该方法返回一个字节字符串,这些字节是示例。。。无论wave文件采用何种格式(您可以使用
.getnchannels
方法确定与将帧分解为样本相关的两个参数,用于通道数,使用
.getsampwidth
方法确定每个样本的字节数)


将字节字符串转换为数字值序列的最佳方法是使用
数组
模块,以及(分别)数组对象的
'B'
'H'
'L'
类型,每个样本1、2、4个字节(在32位Python构建中;您可以使用数组对象的
itemsize
值进行双重检查)。如果您的样本宽度与
array
所能提供的不同,则需要将字节字符串切分(用值为0的字节适当填充每个小片段)并使用模块(但这更笨重、更慢,因此如果可以,请使用
array
)(单声道和立体声测试):

在读取样本(例如,使用wave模块,更多详细信息)后,您可能希望使值的比例介于-1和1之间(这是音频信号的惯例)

在这种情况下,您可以添加:

# scale to -1.0 -- 1.0
max_nb_bit = float(2**(nb_bits-1))  
samples = signal_int / (max_nb_bit + 1.0) 

使用
nb\u bits
位深度和
signal\u int
整数值。

当我尝试.getsamplewidth时,它给了我一个值2,意味着2个字节..当我尝试时。readframes(1)应该返回1帧,然后为我返回,例如“/x03/x16”我猜是2个字节,那么这是否意味着1帧只有1个样本..getnchannels的用途是什么?我想分别从每个帧中提取样本,并用整数表示它们,我怎么能?@kaki,在每个帧中,每个通道都有第一个样本,然后每个通道都有第二个样本,依此类推。所以除非你的声音是mon也就是说,只有一个通道,你必须决定如何处理这些通道(跳过所有通道,但一个除外,求平均值,不管怎样)。假设它是一个通道(mono),最简单,然后
x=array。array('h',w.getframes(1))
x中给你一个数组,第一帧(下一帧,如果在循环中)的所有样本都是整数,正如你所说的那样(
h
,而不是
h
:它们是有符号的)。如果立体声,2个频道,甚至是
x
的索引都有左声道示例。Little endian btw.btw,格式文档中不使用“帧”的概念,而是使用“块”和“子块”,但最后当然是差不多的;-)“KKI,不客气,但要考虑接受帮助你的答案(点击Q左边的勾勾轮廓),因为这是最基本的礼仪。”AlxMyteli为挖掘坟墓而抱歉,但我正在尝试使用RealFrimes(1),我需要它把两个样本分割成两个单独的变量。(基本上把第一个左边的样本放在变量X中,把第一个右边的样本放在变量Y中),但我不知道怎么做,有什么建议吗?你能告诉我如何在不使用scipy的情况下将样本作为浮点数数组来获取吗
import argparse
import itertools
import struct
import sys
import wave

def _struct_format(sample_width, nb_samples):
    return {1:"%db", 2:"<%dh", 4:"<%dl"}[sample_width] % nb_samples

def _mix_samples(samples):
    return sum(samples)//len(samples)

def read_samples(wave_file, nb_frames):
    frame_data = wave_file.readframes(nb_frames)
    if frame_data:
        sample_width = wave_file.getsampwidth()
        nb_samples = len(frame_data) // sample_width
        format = _struct_format(sample_width, nb_samples)
        return struct.unpack(format, frame_data)
    else:
        return ()

def write_samples(wave_file, samples, sample_width):
    format = _struct_format(sample_width, len(samples))
    frame_data = struct.pack(format, *samples)
    wave_file.writeframes(frame_data)

def compatible_input_wave_files(input_wave_files):
    nchannels, sampwidth, framerate, nframes, comptype, compname = input_wave_files[0].getparams()
    for input_wave_file in input_wave_files[1:]:
        nc,sw,fr,nf,ct,cn = input_wave_file.getparams()
        if (nc,sw,fr,ct,cn) != (nchannels, sampwidth, framerate, comptype, compname):
            return False
    return True

def mix_wave_files(output_wave_file, input_wave_files, buffer_size):
    output_wave_file.setparams(input_wave_files[0].getparams())
    sampwidth = input_wave_files[0].getsampwidth()
    max_nb_frames = max([input_wave_file.getnframes() for input_wave_file in input_wave_files])
    for frame_window in xrange(max_nb_frames // buffer_size + 1):
        all_samples = [read_samples(wave_file, buffer_size) for wave_file in input_wave_files]
        mixed_samples = [_mix_samples(samples) for samples in itertools.izip_longest(*all_samples, fillvalue=0)]
        write_samples(output_wave_file, mixed_samples, sampwidth)

def concatenate_wave_files(output_wave_file, input_wave_files, buffer_size):
    output_wave_file.setparams(input_wave_files[0].getparams())
    sampwidth = input_wave_files[0].getsampwidth()
    for input_wave_file in input_wave_files:
        nb_frames = input_wave_file.getnframes()
        for frame_window in xrange(nb_frames // buffer_size + 1):
            samples = read_samples(input_wave_file, buffer_size)
            if samples:
                write_samples(output_wave_file, samples, sampwidth)

def argument_parser():
    parser = argparse.ArgumentParser(description='Mix or concatenate multiple .wav files')
    parser.add_argument('command', choices = ("mix", "concat"), help='command')
    parser.add_argument('output_file', help='ouput .wav file')
    parser.add_argument('input_files', metavar="input_file", help='input .wav files', nargs="+")
    parser.add_argument('--buffer_size', type=int, help='nb of frames to read per iteration', default=1000)
    return parser

if __name__ == '__main__':
    args = argument_parser().parse_args()

    input_wave_files = [wave.open(name,"rb") for name in args.input_files]
    if not compatible_input_wave_files(input_wave_files):
        print "ERROR: mixed wave files must have the same params."
        sys.exit(2)

    output_wave_file = wave.open(args.output_file, "wb")
    if args.command == "mix":
        mix_wave_files(output_wave_file, input_wave_files, args.buffer_size)
    elif args.command == "concat":
        concatenate_wave_files(output_wave_file, input_wave_files, args.buffer_size)

    output_wave_file.close()
    for input_wave_file in input_wave_files:
        input_wave_file.close()
# scale to -1.0 -- 1.0
max_nb_bit = float(2**(nb_bits-1))  
samples = signal_int / (max_nb_bit + 1.0)