The Sun Microsystems .au not the ones from Audacity.
.au was the very first audio format I learned to code.
Although you should always just import the built-in wave library instead of au, I still believe it’s a great place to start learning about structs, how to pack/unpack, and how to work with file headers.

Currently the code only supports PCM32 (Each sample is a 4 byte long); at a later date I will add some more formats if analytics data suggests there’s an interest.


I would’ve written this in python 2, I think it should work in py3 anyway,

from __future__ import division
from struct import pack
from math import sin, pi
def AuHeader(SampleCount,Method="PCM32L"):
    Methods={"MuLaw":(1,1),"PCM8L":(2,1),"PCM16L":(3,2),"PCM32L":(5,4),"PCM32F":(6,4),"PCM64F":(7,8)}
    SampleRate=44100
    (Code,BytesPer)=Methods[Method]
    if Method=="MuLaw":
        SampleRate=8000
    return '.snd'+pack('>5L',24,SampleCount*BytesPer,Code,SampleRate,1)
#Make a header beginning with ".snd" followed by five lots of 4 byte integers,the first represents the header size in bytes, the second is the total number of bytes in the data stream, next is a code representing which encoding is used. 
#We'll exclusively be using PCM32 which is represented by a 5,
#Next is Sample Rate, how many samples per second, we'll be using 44100hz; there are other values, but it's the most common
 
def ListToAu(Samples,Method="PCM32L"):
    File=AuHeader(len(Samples))
    File+=AuBody(Samples)
    return File

def OutputListAu(Samples,Name="test.au",Method="PCM32L"):
    File=open(Name,"w")
    #Graph.ListToGraph(Samples).show()
    File.write(ListToAu(Samples))
    File.close()

def AuBody(Samples,Method="PCM32L"):
    Out=b""
    if Method=="PCM32L":
        Signed=True
        BytesPer=4
        Code=">l"
    Magnitude=2**(BytesPer*8-1)-1
    if Signed:
        for i in Samples:
            j=-1 if i<-1 else 1 if i >1 else i
            Out+=pack(Code,int(Magnitude*j))#Multiply the normalised value of the sample by the Magnitude round it to the nearest integer and pack it into bytestring Out
    else:
        for i in Samples:
            j=-1 if i<-1 else 1 if i >1 else i
            Out+=pack(Code,int(Magnitude*(j+1)))
    return Out

OutputListAu([sin(x/44100*440) for x in range(441000)])#Example

Back to top