dungeon_crawler

view prototype/src/audio/sample.cc @ 69:45172d087ebe

fixed some windows compatibility crap fixed a terrible stack overrun in psys (TODO: remember to fix in libpsys too)
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 07 Oct 2012 03:42:44 +0200
parents aa9e28670ae2
children
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <assert.h>
5 #include <vorbis/vorbisfile.h>
6 #include "openal.h"
7 #include "sample.h"
10 #define CHECK_ERROR \
11 do { \
12 unsigned int err = alGetError(); \
13 if(err != 0) { \
14 fprintf(stderr, "%s:%d: AL error: %#x\n", __FILE__, __LINE__, err); \
15 abort(); \
16 } \
17 } while(0)
20 AudioSample::AudioSample()
21 {
22 albuffer = 0;
23 }
25 AudioSample::~AudioSample()
26 {
27 destroy();
28 }
30 void AudioSample::destroy()
31 {
32 if(albuffer) {
33 alDeleteBuffers(1, &albuffer);
34 albuffer = 0;
35 }
36 }
38 bool AudioSample::load(const char *fname)
39 {
40 OggVorbis_File vf;
41 if(ov_fopen(fname, &vf) != 0) {
42 fprintf(stderr, "failed to open ogg/vorbis file: %s\n", fname);
43 return false;
44 }
45 vorbis_info *vinfo = ov_info(&vf, -1);
46 ALenum alfmt = vinfo->channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
48 printf("loading sample: %s: %ld samples/s, %s (%d chan)\n", fname, vinfo->rate,
49 vinfo->channels == 1 ? "mono" : "stereo", vinfo->channels);
51 long num_samples = ov_pcm_total(&vf, -1) * vinfo->channels;
52 int16_t *samples = new int16_t[num_samples];
54 long bufsz = num_samples * sizeof *samples;
55 long total_read = 0;
56 while(total_read < bufsz) {
57 int bitstream;
58 long rd = ov_read(&vf, (char*)samples + total_read, bufsz, 0, 2, 1, &bitstream);
59 if(!rd) {
60 bufsz = total_read;
61 printf("%s: unexpected eof while reading: %s\n", __FUNCTION__, fname);
62 } else {
63 total_read += rd;
64 }
65 }
67 assert(alGetError() == AL_NO_ERROR);
69 unsigned int bufobj = 0;
70 alGenBuffers(1, &bufobj);
71 if(alGetError()) {
72 fprintf(stderr, "failed to create OpenAL buffer\n");
73 goto err;
74 }
76 alBufferData(bufobj, alfmt, samples, bufsz, vinfo->rate);
77 CHECK_ERROR;
78 if(alGetError()) {
79 fprintf(stderr, "failed to load sample data into OpenAL buffer: %u\n", bufobj);
80 goto err;
81 }
83 ov_clear(&vf);
84 delete [] samples;
86 destroy(); // cleanup previous buffer if any
87 albuffer = bufobj;
88 return true;
90 err:
91 delete [] samples;
92 ov_clear(&vf);
93 if(bufobj) {
94 alDeleteBuffers(1, &bufobj);
95 }
96 return false;
97 }
99 AudioSample *load_audio_sample(const char *fname)
100 {
101 AudioSample *s = new AudioSample;
103 if(!s->load(fname)) {
104 delete s;
105 s = 0;
106 }
107 return s;
108 }
110 void destroy_audio_sample(AudioSample *s)
111 {
112 delete s;
113 }