Completed
Push — master ( 1806b7...defdc1 )
by Matthew
53s
created

ed2d.AudioFile.destroy()   A

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.audioBitdepth = wav.getsampwidth() * 8
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
        al.alSourcei(self.source, al.AL_BUFFER, al.ALint(self.buffer.value))
57
58
        pyBuffer = wav.readframes(wav.getnframes())
59
        print(len(pyBuffer), wav.getnframes())
60
61
        cBuffer = ct.create_string_buffer(pyBuffer)
62
        bufferData = ct.cast(ct.pointer(cBuffer), ct.c_void_p)
63
        al.alBufferData(self.buffer, audioFormat, bufferData, self.audioBitdepth // 8, self.samplerate)
64
        wav.close()
65
66
    def destroy(self):
67
        al.alDeleteSources(1, ct.byref(self.source))
68
        al.alDeleteBuffers(1, ct.byref(self.buffer))
69
70
    def play(self):
71
        al.alSourcePlay(self.source)
72
73
    def stop(self):
74
        al.alSourceStop(self.source)
75
76
    def pause(self):
77
        al.alSourcePause(self.source)
78
79
    def get_pos(self):
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