Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

wav

pyglet

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

The shape of the data is: (88471, 2) rate is: 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. 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()
like image 463
mm_ Avatar asked Jul 11 '18 00:07

mm_


People also ask

Can you split a WAV file?

Just drag-and-drop the file to the Video Splitter main window or use File menu -> Open Media File... and select the . WAV file in the opened dialog box. 3) Now select fragments for editing. Use slider and "Add marker" button (or "M" hot key) to mark one or several beginning and end positions of fragments for saving.

How many channels can a WAV file have?

Since the sampling rate of a WAV file can vary from 1 Hz to 4.3 GHz, and the number of channels can be as high as 65535, . wav files have also been used for non-audio data.


Video Answer


2 Answers

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:

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)
like image 160
Andriy Makukha Avatar answered Oct 05 '22 23:10

Andriy Makukha


Try ffmpeg on the command line:

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)

like image 30
Marichyasana Avatar answered Oct 06 '22 01:10

Marichyasana