rev |
line source |
nuclear@47
|
1 #include <stdio.h>
|
nuclear@47
|
2 #include <stdlib.h>
|
nuclear@47
|
3 #include <assert.h>
|
nuclear@47
|
4 #include <vorbis/vorbisfile.h>
|
nuclear@47
|
5 #include "openal.h"
|
nuclear@47
|
6 #include "sample.h"
|
nuclear@47
|
7
|
nuclear@47
|
8 AudioSample::AudioSample()
|
nuclear@47
|
9 {
|
nuclear@47
|
10 albuffer = 0;
|
nuclear@47
|
11 }
|
nuclear@47
|
12
|
nuclear@47
|
13 AudioSample::~AudioSample()
|
nuclear@47
|
14 {
|
nuclear@47
|
15 destroy();
|
nuclear@47
|
16 }
|
nuclear@47
|
17
|
nuclear@47
|
18 void AudioSample::destroy()
|
nuclear@47
|
19 {
|
nuclear@47
|
20 if(albuffer) {
|
nuclear@47
|
21 alDeleteBuffers(1, &albuffer);
|
nuclear@47
|
22 albuffer = 0;
|
nuclear@47
|
23 }
|
nuclear@47
|
24 }
|
nuclear@47
|
25
|
nuclear@47
|
26 bool AudioSample::load(const char *fname)
|
nuclear@47
|
27 {
|
nuclear@47
|
28 OggVorbis_File vf;
|
nuclear@47
|
29 if(ov_fopen(fname, &vf) != 0) {
|
nuclear@47
|
30 fprintf(stderr, "failed to open ogg/vorbis file: %s\n", fname);
|
nuclear@47
|
31 return false;
|
nuclear@47
|
32 }
|
nuclear@47
|
33 vorbis_info *vinfo = ov_info(&vf, -1);
|
nuclear@47
|
34 ALenum alfmt = vinfo->channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
nuclear@47
|
35
|
nuclear@47
|
36 printf("loading sample: %s: %ld samples/s, %s (%d chan)\n", fname, vinfo->rate,
|
nuclear@47
|
37 vinfo->channels == 1 ? "mono" : "stereo", vinfo->channels);
|
nuclear@47
|
38
|
nuclear@47
|
39 long num_samples = ov_pcm_total(&vf, -1);
|
nuclear@47
|
40 int16_t *samples = new int16_t[num_samples];
|
nuclear@47
|
41
|
nuclear@47
|
42 long bufsz = num_samples * sizeof *samples;
|
nuclear@47
|
43 long total_read = 0;
|
nuclear@47
|
44 while(total_read < bufsz) {
|
nuclear@47
|
45 int bitstream;
|
nuclear@47
|
46 long rd = ov_read(&vf, (char*)samples + total_read, bufsz, 0, 2, 1, &bitstream);
|
nuclear@47
|
47 if(!rd) {
|
nuclear@47
|
48 bufsz = total_read;
|
nuclear@47
|
49 printf("%s: unexpected eof while reading: %s\n", __FUNCTION__, fname);
|
nuclear@47
|
50 } else {
|
nuclear@47
|
51 total_read += rd;
|
nuclear@47
|
52 }
|
nuclear@47
|
53 }
|
nuclear@47
|
54
|
nuclear@47
|
55 assert(alGetError() == AL_NO_ERROR);
|
nuclear@47
|
56
|
nuclear@47
|
57 unsigned int bufobj = 0;
|
nuclear@47
|
58 alGenBuffers(1, &bufobj);
|
nuclear@47
|
59 if(alGetError()) {
|
nuclear@47
|
60 fprintf(stderr, "failed to create OpenAL buffer\n");
|
nuclear@47
|
61 goto err;
|
nuclear@47
|
62 }
|
nuclear@47
|
63
|
nuclear@47
|
64 alBufferData(bufobj, alfmt, samples, bufsz, vinfo->rate);
|
nuclear@47
|
65 if(alGetError()) {
|
nuclear@47
|
66 fprintf(stderr, "failed to load sample data into OpenAL buffer: %u\n", bufobj);
|
nuclear@47
|
67 goto err;
|
nuclear@47
|
68 }
|
nuclear@47
|
69
|
nuclear@47
|
70 ov_clear(&vf);
|
nuclear@47
|
71 delete [] samples;
|
nuclear@47
|
72
|
nuclear@47
|
73 destroy(); // cleanup previous buffer if any
|
nuclear@47
|
74 albuffer = bufobj;
|
nuclear@47
|
75 return true;
|
nuclear@47
|
76
|
nuclear@47
|
77 err:
|
nuclear@47
|
78 delete [] samples;
|
nuclear@47
|
79 ov_clear(&vf);
|
nuclear@47
|
80 if(bufobj) {
|
nuclear@47
|
81 alDeleteBuffers(1, &bufobj);
|
nuclear@47
|
82 }
|
nuclear@47
|
83 return false;
|
nuclear@47
|
84 }
|