AudioFile.destroy()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 3
rs 10
1
2
import ctypes as ct
3
import struct
4
import wave
5
6
from ed2d.openal import al
7
from ed2d.openal import alc
8
from ed2d import typeutils
9
10
class AudioContext(object):
11
    def __init__(self):
12
        self.device = None
13
        self.context = None
14
15
    def create(self):
16
        self.device = alc.alcOpenDevice(None)
17
        if not self.device:
18
            self.destroy()
19
            print("Error OpenAL init error.") # TODO - Make this an exception.
20
            return
21
22
        self.context = alc.alcCreateContext(self.device, None)
23
        alc.alcMakeContextCurrent(self.context)
24
        if not self.context:
25
            self.destroy()
26
            print("Error OpenAL init error.") # TODO - Make this an exception.
27
            return
28
29
    def destroy(self):
30
        alc.alcMakeContextCurrent(None)
31
        if self.context:
32
            alc.alcDestroyContext(self.context)
33
        if self.device:
34
            alc.alcCloseDevice(self.device)
35
36
channelMap = {1:al.AL_FORMAT_MONO16, 2:al.AL_FORMAT_STEREO16}
37
38
class AudioFile(object):
39
    def __init__(self, filePath):
40
        wav = wave.open(filePath, mode='rb')
41
        audioFormat = channelMap[wav.getnchannels()]
42
        self.sampleSize = wav.getsampwidth()
43
        self.samplerate = wav.getframerate()
44
45
        self.source = al.ALuint()
46
        al.alGenSources(1, ct.byref(self.source))
47
48
        al.alSourcef(self.source, al.AL_PITCH, 1.0)
49
        al.alSourcef(self.source, al.AL_GAIN, 1.0)
50
        al.alSource3f(self.source, al.AL_POSITION, 0.0, 0.0, 0.0)
51
        al.alSource3f(self.source, al.AL_VELOCITY, 0.0, 0.0, 0.0)
52
        al.alSourcei(self.source, al.AL_LOOPING, al.AL_FALSE)
53
54
        self.buffer = al.ALuint()
55
        al.alGenBuffers(1, ct.byref(self.buffer))
56
57
        samples = wav.getnframes()
58
        bufferData = (ct.c_ubyte * (samples*2))
59
        bufferData = bufferData(*wav.readframes(samples))
60
61
        al.alBufferData(self.buffer, audioFormat, ct.byref(bufferData), self.sampleSize * samples, self.samplerate)
62
        al.alSourcei(self.source, al.AL_BUFFER, self.buffer.value)
63
        wav.close()
64
65
    def destroy(self):
66
        al.alDeleteSources(1, ct.byref(self.source))
67
        al.alDeleteBuffers(1, ct.byref(self.buffer))
68
69
    def play(self):
70
        al.alSourcePlay(self.source)
71
72
    def stop(self):
73
        al.alSourceStop(self.source)
74
75
    def pause(self):
76
        al.alSourcePause(self.source)
77
78
    def get_pos(self):
79
        # this is super basic and will not work properly with stero audio files...
80
        byteoffset = al.ALint()
81
        al.alGetSourcei(self.source, al.AL_BYTE_OFFSET, ct.byref(byteoffset))
82
        byteoffset = byteoffset.value
83
        return float(byteoffset) / self.samplerate
84
85
    def volume(self, vol):
86
        pass
87
88
89
class Audio(object):
90
    def __init__(self):
91
        self.context = AudioContext()
92
        self.context.create()
93
94
        # setup listener
95
        al.alListener3f(al.AL_POSITION, 0.0, 0.0, 0.0)
96
        al.alListener3f(al.AL_VELOCITY, 0.0, 0.0, 0.0)
97
        al.alListener3f(al.AL_ORIENTATION, 0.0, 0.0, 0.0)
98
99
    def destroy(self):
100
        self.context.destroy()
101