dungeon_crawler

view prototype/src/audio/sample.cc @ 47:d52711f2b9a1

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