dungeon_crawler

annotate 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
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 }