简体   繁体   English

如何使用wavio将双通道wav文件的每个通道分成两个不同的文件? 或另一个图书馆?

[英]How do you separate each channel of a two channel wav file into two different files using wavio? or another library?

The following script plays the original file ok. 以下脚本可以播放原始文件。 I try to separate each channel in the obvious way, but it does not work. 我尝试以明显的方式分离每个频道,但它不起作用。

import os
import wavio
import numpy
import pyglet

file_name = "guitarup_full.wav"

# I get the file !
File = wavio.read(file_name)
rate = File.rate
# it looks good
print File.data.shape
print rate
# and then the channels:
channel_1 = File.data[:,0]
channel_2 = File.data[:,1]
wavio.write("guitar_channel_1.wav", channel_1, rate )
wavio.write("guitar_channel_2.wav", channel_2, rate )

# now we try to play:
source =  pyglet.resource.media(file_name, streaming=False)
source_ch1 =  pyglet.resource.media("guitar_channel_1.wav", streaming=False)
source_ch2 =  pyglet.resource.media("guitar_channel_2.wav", streaming=False)

#uncomment the one you want to listen.
source.play()
#source_ch1.play()
#source_ch2.play()

pyglet.app.run()

The first sounds like a guitar, the second and third like Gaussian noise. 第一个听起来像吉他,第二个和第三个听起来像高斯噪音。 Can someone tell me what is wrong with it? 有人能告诉我它有什么问题吗?

The audio file I used is: https://www.freesounds.info/global/wav.php?fileid=11 我使用的音频文件是: https//www.freesounds.info/global/wav.php?fileid = 11

The shape of the data is: (88471, 2) rate is: 44100 数据的形状为:(88471,2),速率为:44100

Also, if I play the file in another player, I get the same: Gaussian Noise. 另外,如果我在另一个播放器中播放该文件,我会得到相同的结果:高斯噪声。

Note: The use of pyglet is superfluous for the problem. 注意: pyglet的使用对于这个问题来说是多余的。 If you use it to investigate this issue, make sure the files are in a folder registered in the resources folder. 如果您使用它来调查此问题,请确保文件位于资源文件夹中注册的文件夹中。 To do that: 要做到这一点:

pyglet.resource.path.append("your_sounds_location")
pyglet.resource.reindex()

I don't know what is wrong with the wavio code, but here's how you can separate WAV channel using standard Python module wave (which is also used by wavio) and numpy: 我不知道wavio代码有什么问题,但是这里你可以使用标准的Python模块wave (wavio也使用)和numpy来分离WAV通道:

import wave
import numpy as np

def save_wav_channel(fn, wav, channel):
    '''
    Take Wave_read object as an input and save one of its
    channels into a separate .wav file.
    '''
    # Read data
    nch   = wav.getnchannels()
    depth = wav.getsampwidth()
    wav.setpos(0)
    sdata = wav.readframes(wav.getnframes())

    # Extract channel data (24-bit data not supported)
    typ = { 1: np.uint8, 2: np.uint16, 4: np.uint32 }.get(depth)
    if not typ:
        raise ValueError("sample width {} not supported".format(depth))
    if channel >= nch:
        raise ValueError("cannot extract channel {} out of {}".format(channel+1, nch))
    print ("Extracting channel {} out of {} channels, {}-bit depth".format(channel+1, nch, depth*8))
    data = np.fromstring(sdata, dtype=typ)
    ch_data = data[channel::nch]

    # Save channel to a separate file
    outwav = wave.open(fn, 'w')
    outwav.setparams(wav.getparams())
    outwav.setnchannels(1)
    outwav.writeframes(ch_data.tostring())
    outwav.close()

wav = wave.open(WAV_FILENAME)
save_wav_channel('ch1.wav', wav, 0)
save_wav_channel('ch2.wav', wav, 1)

Try ffmpeg on the command line: 在命令行上尝试ffmpeg:

Output each channel in stereo input to individual mono files: 将立体声输入中的每个通道输出到单个单声道文件

ffmpeg -i stereo.wav -map_channel 0.0.0 left.wav -map_channel 0.0.1 right.wav

I tried it on your file and it seems to work. 我在你的文件上试了一下它似乎工作。

If you need it to be in a python program just use os.system(cmd) 如果你需要它在python程序中只需使用os.system(cmd)

Method 1 (Using ffmpeg) 方法1 (使用ffmpeg)

You can use ffmpeg to split a n-channeled .wav like this: 你可以使用ffmpeg来分割一个n-channel的.wav,如下所示:

ffmpeg -i input.wav -map 0:1 1.wav -map 0:2 2.wav -map 0:3 3.wav........

You can run this is python using: 您可以使用以下命令运行python:

import os
os.system(ffmpeg -i 14ch.mov -map 0:1 1.wav -map 0:2 2.wav -map 0:3 3.wav........)

Method 2 (Using sox) 方法2 (使用sox)

Install sox from here 这里安装sox

Then try this: 然后尝试这个:

sox infile.wav outfile_left.wav remix 1
sox infile.wav outfile_right.wav remix 2

Again you can run this in python using os.system 你可以再次使用os.system在python中运行它

I think that you are trying to make it much more complicated than it needs to be. 我认为你试图使它变得比它需要的复杂得多。 If you don't mind using scipy than separating the channels comes down to: 如果你不介意使用scipy不是分离频道归结为:

from scipy.io import wavfile

fs, data = wavfile.read('guitarup_full.wav')            # reading the file

wavfile.write('guitar_channel_1.wav', fs, data[:, 0])   # saving first column which corresponds to channel 1
wavfile.write('guitar_channel_2.wav', fs, data[:, 1])   # saving second column which corresponds to channel 2

Thanks to everyone for taking the time to read and run my scripts. 感谢大家花时间阅读和运行我的脚本。 I finally found a solution. 我终于找到了解决方案。 Follow the steps in this order: 按照此顺序中的步骤操作:

First, uninstall wavio by: 首先,卸载wavio:

pip uninstall wavio

Second, uninstall numpy too: 其次,卸载numpy:

pip uninstall numpy

Finally, install wavio again. 最后,再次安装wavio。 numpy will be installed as a dependency: numpy将作为依赖项安装:

pip install wavio

numpy will be installed as a dependency. numpy将作为依赖项安装。

Installing collected packages: numpy, wavio
Successfully installed numpy-1.14.5 wavio-0.0.4

Then my original script will deliver the solution needed. 然后我的原始脚本将提供所需的解决方案。

The use of ffmpeg as @Marichyasana suggested is a good workaround. 使用ffmpeg作为@Marichyasana建议是一个很好的解决方法。 However python libraries (such as pyglet, python audio tools, etc) have problems reading these output files back. 但是python库(例如pyglet,python音频工具等)在读取这些输出文件时遇到了问题。

I hope people find this solution helpful ! 我希望人们觉得这个解决方案很有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 wavio api 从数据中写入.wav 文件 - How to write .wav file from data using wavio api 如何在 python 中写入多通道 wav 文件 - How to write multi channel wav file in python 如何使用python连接两个wav文件? - How to join two wav files using python? 如何计算文本文件中的两个单独的行并断言它们彼此相等? - How do you count two separate lines in a text file and assert that they are equal to one another? 如何获得每个通道的平均和最大音量的立体声WAV文件? 例如,每秒获取阵列中的卷? - How to get a stereo wav file of the average and maximum volume for each channel? Get the volume in an array on a per second, for example? 如何将两个声道的音频转换为一个声道的音频 - How to convert two channel audio into one channel audio 如何使用 python 中的颜色通道分离图像? - how to separate image using color channel in python? 如何使用 asammdf 库计算 mdf 文件中的通道? - How to count a channel in mdf file using asammdf library? 如何使 message.channel.send 命令需要来自同一个库的两个单词? (Python 和 Discord.py) - How do I make a message.channel.send command require two words from the same library? (Python and Discord.py) 如何从频道 ID 获取频道 object? - How do you get a channel object from a channel ID?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM