dungeon_crawler

diff 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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/prototype/src/audio/sample.cc	Sun Sep 16 08:16:50 2012 +0300
     1.3 @@ -0,0 +1,84 @@
     1.4 +#include <stdio.h>
     1.5 +#include <stdlib.h>
     1.6 +#include <assert.h>
     1.7 +#include <vorbis/vorbisfile.h>
     1.8 +#include "openal.h"
     1.9 +#include "sample.h"
    1.10 +
    1.11 +AudioSample::AudioSample()
    1.12 +{
    1.13 +	albuffer = 0;
    1.14 +}
    1.15 +
    1.16 +AudioSample::~AudioSample()
    1.17 +{
    1.18 +	destroy();
    1.19 +}
    1.20 +
    1.21 +void AudioSample::destroy()
    1.22 +{
    1.23 +	if(albuffer) {
    1.24 +		alDeleteBuffers(1, &albuffer);
    1.25 +		albuffer = 0;
    1.26 +	}
    1.27 +}
    1.28 +
    1.29 +bool AudioSample::load(const char *fname)
    1.30 +{
    1.31 +	OggVorbis_File vf;
    1.32 +	if(ov_fopen(fname, &vf) != 0) {
    1.33 +		fprintf(stderr, "failed to open ogg/vorbis file: %s\n", fname);
    1.34 +		return false;
    1.35 +	}
    1.36 +	vorbis_info *vinfo = ov_info(&vf, -1);
    1.37 +	ALenum alfmt = vinfo->channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
    1.38 +
    1.39 +	printf("loading sample: %s: %ld samples/s, %s (%d chan)\n", fname, vinfo->rate,
    1.40 +			vinfo->channels == 1 ? "mono" : "stereo", vinfo->channels);
    1.41 +
    1.42 +	long num_samples = ov_pcm_total(&vf, -1);
    1.43 +	int16_t *samples = new int16_t[num_samples];
    1.44 +
    1.45 +	long bufsz = num_samples * sizeof *samples;
    1.46 +	long total_read = 0;
    1.47 +	while(total_read < bufsz) {
    1.48 +		int bitstream;
    1.49 +		long rd = ov_read(&vf, (char*)samples + total_read, bufsz, 0, 2, 1, &bitstream);
    1.50 +		if(!rd) {
    1.51 +			bufsz = total_read;
    1.52 +			printf("%s: unexpected eof while reading: %s\n", __FUNCTION__, fname);
    1.53 +		} else {
    1.54 +			total_read += rd;
    1.55 +		}
    1.56 +	}
    1.57 +
    1.58 +	assert(alGetError() == AL_NO_ERROR);
    1.59 +
    1.60 +	unsigned int bufobj = 0;
    1.61 +	alGenBuffers(1, &bufobj);
    1.62 +	if(alGetError()) {
    1.63 +		fprintf(stderr, "failed to create OpenAL buffer\n");
    1.64 +		goto err;
    1.65 +	}
    1.66 +
    1.67 +	alBufferData(bufobj, alfmt, samples, bufsz, vinfo->rate);
    1.68 +	if(alGetError()) {
    1.69 +		fprintf(stderr, "failed to load sample data into OpenAL buffer: %u\n", bufobj);
    1.70 +		goto err;
    1.71 +	}
    1.72 +
    1.73 +	ov_clear(&vf);
    1.74 +	delete [] samples;
    1.75 +
    1.76 +	destroy();	// cleanup previous buffer if any
    1.77 +	albuffer = bufobj;
    1.78 +	return true;
    1.79 +
    1.80 +err:
    1.81 +	delete [] samples;
    1.82 +	ov_clear(&vf);
    1.83 +	if(bufobj) {
    1.84 +		alDeleteBuffers(1, &bufobj);
    1.85 +	}
    1.86 +	return false;
    1.87 +}