Sam Perry
Sam Perry

Reputation: 155

Wave file sample editing using Python AudioTools

I am trying to create a Python script that is able to open an audio file, read the PCM data, and output another audio file using this PCM data. (eventually I want to be able to apply processes to the data)

I am currently using python audiotools as it appears to be able to do this with a fair few formats.

I have managed to read the data and convert to a FramesList of floating point values which is perfect for editing, though I cannot work out the process of writing the processed FramesList back to a .wav file. to_bytes() converts the data into a raw pcm string but I am unsure how to get this raw data back into a wav file?

from audiotools import *
from argparse import ArgumentParser

def get_info(audio_file, main_args):
    """
    create a dictionary of information for the audiofile object.

    """
    info = {}
    info["channels"] = audio_file.channels()
    info["channel_mask"] = audio_file.channel_mask()
    info["bits"] = audio_file.bits_per_sample()
    info["sample_rate"] = audio_file.sample_rate()
    info["frames"] = audio_file.total_frames()
    info["length"] = audio_file.seconds_length()
    info["seekable"] = audio_file.seekable()
    info["verified"] = audio_file.verify()
    info["chunks"] = audio_file.has_foreign_wave_chunks()
    info["available"] = audio_file.available(BIN)
    info["header"], info["footer"] = audio_file.wave_header_footer()

    if main_args.verbose:
        print "No. of Channels:\t\t", info["channels"]
        print "Channel mask:\t\t\t", info["channel_mask"]
        print "Bits per sample:\t\t", info["bits"], "BIT"
        print "Sample Rate:\t\t\t", (info["sample_rate"]/1000.0), "k"
        print "Number of Frames:\t\t", info["frames"]
        print "Audio Length:\t\t\t", info["length"], "seconds"
        print "Audio File Seekable?:\t\t", info["seekable"]
        print "File has foreign chunks?:\t", info["chunks"]
        print "Correct Binaries present?:\t", info["available"]
    return info

def main():
    parser = ArgumentParser()
    parser.add_argument(
        "-v",
        "--verbose",
        help = "Run program verbosely",
        default = False,
        action = "store_true",
    )

    main_args = parser.parse_args()

    #open audio file as an AudioFile object
    audio_file =  open("/Users/samperry/piano2.wav")
    file_info = get_info(audio_file, main_args)

    #Creates a WaveReader object from the AudioFile Object
    pcm_data = audio_file.to_pcm()

    #Creates a FrameList object from WaveReader object. Currently reads all
    #frames in file
    frame_list = pcm_data.read(file_info["frames"])

    #Convert samples to floats (-1.0 - +1.0)
    float_frame_list = frame_list.to_float()

    #eventually do some signal processing here...

    #Convert back to integer FrameList
    output_framelist = float_frame_list.to_int(file_info["bits"])

    #now back to raw bytes
    output_data = output_framelist.to_bytes(False, True)

if __name__ == "__main__":
    main()

Upvotes: 0

Views: 2082

Answers (2)

travc
travc

Reputation: 1859

If you are just working with wav files, then you can use the wave python module. It is much much simpler than audiotools.

If you need to handle other file formats, and don't mind using an external program, you could just output the raw data to a file and then convert it to whatever you want using sox.
You might look at this answer about reading data to get some ideas.

Upvotes: 0

jazdev
jazdev

Reputation: 486

Have you tried PyDub? It allows you to manipulate audio with an simple and easy high level interface.

Upvotes: 1

Related Questions