JBo
JBo

Reputation: 11

How do I open an AIFC file in Python to append marker data to the file?

I have imported the module named aifc into Python on a Mac, I'm running the Python 3.3 and Mac OS X 10.8.2.

I'm trying to simply copy the marker data from one aifc file to another aifc file. I can successfully open the first file and read the marker data, that works well. But when I open the second aifc file the method aifc.open("file2.aifc", 'w') immediately deletes all the contents of that file. So I end up with an aifc file with the right markers but no music!

I did some research and found that it is the correct behavior of Python to delete the contents of a file when it is opened with mode 'w'. I've read that mode 'a' allows a file to be appended. However the aifc.open() method gives me an error when I try mode 'a' , the interpreter says that the mode must be "r" "rb" "w" or "wb".

Hence I'm stuck -- perhaps this is an old library and I should be using something different.

If so, can someone direct me to how I could access an Apple Objective C library within Python to manipulate audio files. I think there is a library called Audio File Services but I'm unclear how I could use that within Python.

Although I'm not new to programming, I'm new to Python, so apologies if these are newbie questions.

Upvotes: 1

Views: 650

Answers (1)

NinthTest
NinthTest

Reputation: 163

Just encountered this myself!

The aifc.open helper function restricts the modes to 'r', 'rb', 'w', and 'wb' explicitly. It appears that the classes in this module (Aifc_read and Aifc_write) are only for reading an existing AIFC file or creating an entirely new AIFC file from scratch, respectively.

Here's what I've come up with as a readable+writeable AIFC file utility using this module:

import aifc
import sys


class AIFC(aifc.Aifc_write, aifc.Aifc_read):

    def __init__(self, f):
        aifc.Aifc_write.initfp(self, f)
        aifc.Aifc_read.initfp(self, f)


if (__name__ == "__main__"):
    f = open(sys.argv[1], "rb+")
    a = AIFC(f)

    # read test
    print("%s channels, %s bits, %s Hz sampling rate, %s frames" %
          (a.getnchannels(), a.getsampwidth() * 8, a.getframerate(),
           a.getnframes()))

    # write ("identity") test
    data = a.readframes(a.getnframes())
    a.setpos(0)
    a.writeframes(data)
    a.close()   # f.close()

It hasn't been tested extensively, but it does seem to do the trick. I've run several original AIFs through it, and they all play back correctly in Audacity.

Upvotes: 1

Related Questions