Linux and python: Combining multiple wave files to one wave file - python

I am looking for a way that I can combine multiple wave files into one wave file using python and run it on linux. I don't want to use any add on other than the default shell command line and default python modules.
For example, if I have a.wav and b.wav. I want to create a c.wav which start with the content from a.wav then b.wav.
I've found wave module, that I can open a wave file and write into a new file. Since i'm really new in this audio world. I still can't figure out how to do it. Below is my code
import struct, wave
waveFileA = wave.open('./a.wav', 'r')
waveFileB = wave.open('./b.wav', 'r')
waveFileC = wave.open('./c.wav', 'w')
lengthA = waveFileA.getnframes()
for i in range(0,lengthA):
waveFileC.writeframes(waveFileA.readframes(1))
lengthB = waveFileB.getnframes()
for i in range(0,lengthB):
waveFileC.writeframes(waveFileB.readframes(1))
waveFileA.close()
waveFileB.close()
waveFileC.close()
When i run this code, I got this error:
wave.Error: # channels not specified
Please can any one help me?

You need to set the number of channels, sample width, and frame rate:
waveFileC.setnchannels(waveFileA.getnchannels())
waveFileC.setsampwidth(waveFileA.getsampwidth())
waveFileC.setframerate(waveFileA.getframerate())
If you want to handle a.wav and b.wav having different settings, you'll want to use something like pysox to convert them to the same settings, or for nchannels and sampwidth you may be able to tough through it yourself.

Looks like you need to call n=waveFileA.getnchannels() to find out how many channels the first input file uses, likewise for waveFileB, then you'll need to use waveFileC.setnchannels(n) to tell it how many channels to put in the outgoing file. I don't know how it will handle input files with different numbers of channels...

Here is the answer I am looking for
How to join two wav files using python?
(look for a thread by Tom 10)
It's in another thread. some one already solved this problem.

Related

How to merge wma files to mp3 (with header editing)?

I have some .wma file which I am trying to merge into a single one...
I started with python reading files in bytes and writing them into a new one, just as I tried the cmd command copy /b file1.wma + file2.wma + else.wma total.wma
all came up with the same result: my total file was as large in byte as real total of my segments, but when I try to open the file it plays the first segment both in length(time) and content -meaning that I have a 15 MB 10 second voice :-))
I tried to do that with different .wma files but each time it is the first one in length and content and total of them in size.
My assumption is that probably some were my .wma data frame (maybe in file header) there is a data about length of current file, so that after merging the file when the player attempts to play the file reads that data about time and stops after the time. or some like that.
so I need to edit those data frame or header (if even exist) in a way that matches my final output or just simply ignore that.
but I don't know whether it is right or how I can do that
.wma file sample: https://github.com/Fsunroo/PowerPointVoiceExtract (media1.wma and media2.wma for example)
note: there is no such problem with web applications that join songs (maybe they do editing header??!)
Note2: it is a part of my code witch extract voice from a power point file.
I solved the problem by using moviepy.editor
the corrected project is accessible at: https://github.com/Fsunroo/PowerPointVoiceExtract

convert eye-tracking .edf file to ASC/CSV format

I have a recording of tracking data in .edf format (SR-RESEARCH eyelink). I want to convert it to ASC/CSV format in python. I have the GUI application but I want to do it programmatically (in Python).
I found the package pyEDFlib but couldn't find an example to how convert the eye-tracking .edf file to .asc or .csv.
What will the best best way to do it?
Thanks
If I trust the page here: http://pyedflib.readthedocs.io/en/latest, you can run through all the signals in the file this way:
import pyedflib
import numpy as np
f = pyedflib.EdfReader("data/test_generator.edf")
n = f.signals_in_file
signal_labels = f.getSignalLabels()
sigbufs = np.zeros((n, f.getNSamples()[0]))
for i in np.arange(n):
sigbufs[i, :] = f.readSignal(i)
The pyEDFlib library simply reads the file into an EdfReader object.
Then you just need to go through and make row for each.
I assume that signal_labels (in the code above) will be an array with all the labels so make a comma separated string out of them
signal_labels_row = ",".join(signal_labels)
Then do the same for each signal, 1 comma separated String for each
Then simply write them in a file.
I can see they provide an example of how to read a file and extract all the data you need here
https://github.com/holgern/pyedflib/blob/master/demo/readEDFFile.py
Based on your answers i have created this python3 script to export all singnals to multiple .csv files https://github.com/folkien/pyEdfToCsv

reading .wav files in python

I'm trying (for a course) to read a sound file .wav via ipython. When I try the 'normal' code to read a file:
from scipy.io.wavfile import read
(fs,x) = read ('/Users/joehigham/Desktop/Audio_1.wav')
I get the well known traceback call of
ValueError: string size must be a multiple of element size
Can anyone point me in the right direction as to why this happens, and of course how can I right the problem?
Thanks in advance - I did look round SO for the solution, but nothing (that I found) seems to match this problem with sound files.
Your wav file probably has 24 bit data. You can check with:
import wave
w = wave.open("filename.wav")
print(w.getsampwidth())
If the value printed is 3, your data is 24 bit. If that is the case, scipy.io.wavfile won't work. I wrote a reader that handles 24 bit data; see https://github.com/WarrenWeckesser/wavio (which replaced the gist at https://gist.github.com/WarrenWeckesser/7461781). The reader is also on PyPI.

How can I make a siren noise in Python?

I'm trying to make a siren sound in python with beeps, but had no success..
I'm trying something like
winsound.Beep(700,500)
winsound.Beep(710,500)
winsound.Beep(720,500)
...
It's a better way to do it? And play it?
Without external files...
Thx
Record a high quality siren as a WAV file (Audacity is a nice tool for this task, and might even provide the right mix of sound generators for this) and use PlaySound.
winsound.PlaySound('siren.wav', winsound.SND_FILENAME)
You could also bundle it into the script as a string to avoid having a separate file:
siren = base64.b64decode('''
<base64-encoded data>
''')
winsound.PlaySound(siren, winsound.SND_MEMORY)
To create the data for siren, run the WAV file through a base64 encoder (e.g., here is a basic command-line tool — the download includes a win32 exe) and paste the output into the siren string. Base64 isn't a requirement, by the way; it's just a convenient way to embed binary data into a Python source file.
I remember using something similar on QBASIC when I was still a kid:
DO
FOR n = -180 TO 180 STEP .1
f = 440 + 50 * SIN(n)
SOUND f, 1
NEXT
LOOP
SOUND f, 1 should be the same thing as winsound.Beep, with pitch and duration. It used to work great but since I took the snippet here I'm not sure I did exactly this way.
It's just to give you the idea..

Python open raw audio data file

I have these files with the extension ".adc". They are simply raw data files. I can open them with Audacity using File->Import->Raw data with encoding "Signed 16 bit" and sample rate "16000 Khz".
I would like to do the same with python. I think that audioop module is what I need, but I can't seem to find examples on how to use it for something that simple.
The main goal is to open the file and play a certain location in the file, for example from the second 10 to the second 20. Is there something out there for my task ?
Thanx in advance.
For opening the file, you just need file().
For finding a location, you don't need audioop: you just need to convert seconds to bytes and get the required bytes of the file. For instance, if your file is 16 kHz 16bit mono, each second is 32,000 bytes of data. So the 10th second is 320kB into the file. Just seek to the appropriate place in the file and then read the appropriate number of bytes.
And audioop can't help you with the hardest part: namely, playing the audio. The correct way to do this very much depends on your OS.
EDIT: Sorry, I just noticed your username is "thelinuxer". Consider pyAO for playing audio from Python on Linux. You will probably need to change the sample format to play the audio---audioop will help you with this (see ratecv, tomono/tostereo, lin2lin, and bias)
Thanx a lot I was able to do the following:
def play_data(filename, first_sec, second_sec):
import ao
from ao import AudioDevice
dev = AudioDevice(2, bits=16, rate=16000,channels=1)
f = open(filename, 'r')
data_len = (second_sec-first_sec)*32000
f.seek(32000*first_sec)
data = f.read(data_len)
dev.play(data)
f.close()
play_data('AR001_3.adc', 2.5, 5)
You can use PySoundFile to open the file as a NumPy array and play it with python-sounddevice.
import soundfile as sf
import sounddevice as sd
sig, fs = sf.read('myfile.adc', channels=2, samplerate=16000,
format='RAW', subtype='PCM_16')
sd.play(sig, fs)
You can use indexing on the NumPy array to select a certain part of the audio data.

Categories

Resources