Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append data to a wave soundfile without loading its currrent content

Tags:

python

audio

wave

I'm trying to append data to a sound file without loading its contents(because it may have gigabytes of data), I'm using pysoundfile library currently, I've figured out a way to do it for wave64, but in wav, for some reason it's throwing an error.

According to the pysoundfile docs, when a SoundFile is opened with a file descriptor it should write without truncating, so thats what I'm doing currently

    fd = open('foo.wav',mode='ab')
    with sf.SoundFile(fd, mode = 'w', samplerate = self._samplerate,channels = self._channels, format = 'wav') as wfile:
        wfile.seek(0,sf.SEEK_END)
        wfile.write(self._samples)
        wfile.close()
    fd.close()

When I'm using wave filetype the following error occurs:

RuntimeError: Error opening <_io.BufferedWriter name='../datasets/emddf_clean/qcoisa.wav'>: Unspecified internal error.

But with a file formated in w64 it works somehow... If someone could shed a light on me that would be amazing, Thanks in advance!

like image 355
Manel Pereira Avatar asked Oct 15 '22 15:10

Manel Pereira


1 Answers

I managed to do exactly what i want, without using the file descriptor explicitly:

    with sf.SoundFile(path['full_path'], mode = 'r+') as wfile:
        wfile.seek(0,sf.SEEK_END)
        wfile.write(self._samples)

If the file is in r+ mode(read/write), it supports seeking, meaning we can point to the end of the file allowing to append. The only problem is if the file doesn't already exist it will throw an error, but you can easily fix it by doing something along these lines:

    if(self.mode == my_utils.APPEND and os.path.isfile(path['full_path'])):
        with sf.SoundFile(path['full_path'], mode = 'r+', samplerate = samplerate) as wfile:
            wfile.seek(0,sf.SEEK_END)
            wfile.write(self.file.getSamples())
    else:
        sf.write(path['full_path'], self.file.getSamples(), samplerate,format=path['extension']) # writes to the new file 
    return

Hope I was clear and help someone!

like image 85
Manel Pereira Avatar answered Oct 20 '22 14:10

Manel Pereira