dungeon_crawler

changeset 47:d52711f2b9a1

started writting audio code
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 16 Sep 2012 08:16:50 +0300
parents f3030df27110
children aa9e28670ae2
files prototype/Makefile.in prototype/src/audio/audio.cc prototype/src/audio/audio.h prototype/src/audio/openal.h prototype/src/audio/sample.cc prototype/src/audio/sample.h prototype/src/cfg.cc prototype/src/cfg.h prototype/src/main.cc
diffstat 9 files changed, 192 insertions(+), 4 deletions(-) [+]
line diff
     1.1 --- a/prototype/Makefile.in	Thu Sep 13 06:33:51 2012 +0300
     1.2 +++ b/prototype/Makefile.in	Sun Sep 16 08:16:50 2012 +0300
     1.3 @@ -1,21 +1,29 @@
     1.4 -csrc = $(wildcard src/*.c) $(wildcard vmath/*.c) $(wildcard drawtext/*.c)
     1.5 -ccsrc = $(wildcard src/*.cc) $(wildcard vmath/*.cc)
     1.6 +csrc = $(wildcard src/*.c) \
     1.7 +	   $(wildcard vmath/*.c) \
     1.8 +	   $(wildcard drawtext/*.c)
     1.9 +
    1.10 +ccsrc = $(wildcard src/*.cc) \
    1.11 +		$(wildcard src/audio/*.cc) \
    1.12 +		$(wildcard vmath/*.cc)
    1.13 +
    1.14  obj = $(csrc:.c=.o) $(ccsrc:.cc=.o)
    1.15  dep = $(obj:.o=.d)
    1.16  bin = proto
    1.17  
    1.18  warn = -Wall -Wno-format-extra-args -Wno-char-subscripts
    1.19  
    1.20 -inc = -I. -Ivmath -Idrawtext `pkg-config --cflags freetype2`
    1.21 +inc = -I. -Isrc/audio -Ivmath -Idrawtext `pkg-config --cflags freetype2`
    1.22  
    1.23  CFLAGS = -pedantic $(warn) $(dbg) $(opt) $(inc)
    1.24  CXXFLAGS = $(CFLAGS) $(cxx11_cflags)
    1.25 -LDFLAGS = $(cxx11_ldflags) $(libgl) -lm -lassimp -limago -lpsys `pkg-config --libs freetype2`
    1.26 +LDFLAGS = $(cxx11_ldflags) $(libgl) $(libal) -lvorbisfile -lm -lassimp -limago -lpsys `pkg-config --libs freetype2`
    1.27  
    1.28  ifeq ($(shell uname -s), Darwin)
    1.29  	libgl = -framework OpenGL -framework GLUT -lglew
    1.30 +	libal = -framework OpenAL
    1.31  else
    1.32  	libgl = -lGL -lGLU -lglut -lGLEW
    1.33 +	libal = -lopenal
    1.34  endif
    1.35  
    1.36  $(bin): $(obj) Makefile
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/prototype/src/audio/audio.cc	Sun Sep 16 08:16:50 2012 +0300
     2.3 @@ -0,0 +1,44 @@
     2.4 +#include <stdio.h>
     2.5 +#include "openal.h"
     2.6 +#include "audio.h"
     2.7 +
     2.8 +#define CHECK_ERROR \
     2.9 +    do { \
    2.10 +        unsigned int err = alGetError(); \
    2.11 +        if(err != 0) { \
    2.12 +            fprintf(stderr, "%s:%d: AL error: %#x\n", __FILE__, __LINE__, err); \
    2.13 +            abort(); \
    2.14 +        } \
    2.15 +    } while(0)
    2.16 +
    2.17 +static ALCdevice *dev;
    2.18 +static ALCcontext *ctx;
    2.19 +
    2.20 +
    2.21 +bool init_audio()
    2.22 +{
    2.23 +	if(dev) {
    2.24 +		return true;
    2.25 +	}
    2.26 +
    2.27 +	if(!(dev = alcOpenDevice(0))) {
    2.28 +		fprintf(stderr, "failed to open OpenAL device\n");
    2.29 +		return false;
    2.30 +	}
    2.31 +	ctx = alcCreateContext(dev, 0);
    2.32 +	alcMakeContextCurrent(ctx);
    2.33 +
    2.34 +	alGetError();	// clear error code
    2.35 +	return true;
    2.36 +}
    2.37 +
    2.38 +void destroy_audio()
    2.39 +{
    2.40 +	alcMakeContextCurrent(0);
    2.41 +	if(ctx) {
    2.42 +		alcDestroyContext(ctx);
    2.43 +	}
    2.44 +	if(dev) {
    2.45 +		alcCloseDevice(dev);
    2.46 +	}
    2.47 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/prototype/src/audio/audio.h	Sun Sep 16 08:16:50 2012 +0300
     3.3 @@ -0,0 +1,8 @@
     3.4 +#ifndef AUDIO_H_
     3.5 +#define AUDIO_H_
     3.6 +
     3.7 +bool init_audio();
     3.8 +void destroy_audio();
     3.9 +
    3.10 +
    3.11 +#endif	/* AUDIO_H_ */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/prototype/src/audio/openal.h	Sun Sep 16 08:16:50 2012 +0300
     4.3 @@ -0,0 +1,12 @@
     4.4 +#ifndef OPENAL_H_
     4.5 +#define OPENAL_H_
     4.6 +
     4.7 +#ifndef __APPLE__
     4.8 +#include <AL/al.h>
     4.9 +#include <AL/alc.h>
    4.10 +#else
    4.11 +#include <OpenAL/al.h>
    4.12 +#include <OpenAL/alc.h>
    4.13 +#endif
    4.14 +
    4.15 +#endif	/* OPENAL_H_ */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/prototype/src/audio/sample.cc	Sun Sep 16 08:16:50 2012 +0300
     5.3 @@ -0,0 +1,84 @@
     5.4 +#include <stdio.h>
     5.5 +#include <stdlib.h>
     5.6 +#include <assert.h>
     5.7 +#include <vorbis/vorbisfile.h>
     5.8 +#include "openal.h"
     5.9 +#include "sample.h"
    5.10 +
    5.11 +AudioSample::AudioSample()
    5.12 +{
    5.13 +	albuffer = 0;
    5.14 +}
    5.15 +
    5.16 +AudioSample::~AudioSample()
    5.17 +{
    5.18 +	destroy();
    5.19 +}
    5.20 +
    5.21 +void AudioSample::destroy()
    5.22 +{
    5.23 +	if(albuffer) {
    5.24 +		alDeleteBuffers(1, &albuffer);
    5.25 +		albuffer = 0;
    5.26 +	}
    5.27 +}
    5.28 +
    5.29 +bool AudioSample::load(const char *fname)
    5.30 +{
    5.31 +	OggVorbis_File vf;
    5.32 +	if(ov_fopen(fname, &vf) != 0) {
    5.33 +		fprintf(stderr, "failed to open ogg/vorbis file: %s\n", fname);
    5.34 +		return false;
    5.35 +	}
    5.36 +	vorbis_info *vinfo = ov_info(&vf, -1);
    5.37 +	ALenum alfmt = vinfo->channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
    5.38 +
    5.39 +	printf("loading sample: %s: %ld samples/s, %s (%d chan)\n", fname, vinfo->rate,
    5.40 +			vinfo->channels == 1 ? "mono" : "stereo", vinfo->channels);
    5.41 +
    5.42 +	long num_samples = ov_pcm_total(&vf, -1);
    5.43 +	int16_t *samples = new int16_t[num_samples];
    5.44 +
    5.45 +	long bufsz = num_samples * sizeof *samples;
    5.46 +	long total_read = 0;
    5.47 +	while(total_read < bufsz) {
    5.48 +		int bitstream;
    5.49 +		long rd = ov_read(&vf, (char*)samples + total_read, bufsz, 0, 2, 1, &bitstream);
    5.50 +		if(!rd) {
    5.51 +			bufsz = total_read;
    5.52 +			printf("%s: unexpected eof while reading: %s\n", __FUNCTION__, fname);
    5.53 +		} else {
    5.54 +			total_read += rd;
    5.55 +		}
    5.56 +	}
    5.57 +
    5.58 +	assert(alGetError() == AL_NO_ERROR);
    5.59 +
    5.60 +	unsigned int bufobj = 0;
    5.61 +	alGenBuffers(1, &bufobj);
    5.62 +	if(alGetError()) {
    5.63 +		fprintf(stderr, "failed to create OpenAL buffer\n");
    5.64 +		goto err;
    5.65 +	}
    5.66 +
    5.67 +	alBufferData(bufobj, alfmt, samples, bufsz, vinfo->rate);
    5.68 +	if(alGetError()) {
    5.69 +		fprintf(stderr, "failed to load sample data into OpenAL buffer: %u\n", bufobj);
    5.70 +		goto err;
    5.71 +	}
    5.72 +
    5.73 +	ov_clear(&vf);
    5.74 +	delete [] samples;
    5.75 +
    5.76 +	destroy();	// cleanup previous buffer if any
    5.77 +	albuffer = bufobj;
    5.78 +	return true;
    5.79 +
    5.80 +err:
    5.81 +	delete [] samples;
    5.82 +	ov_clear(&vf);
    5.83 +	if(bufobj) {
    5.84 +		alDeleteBuffers(1, &bufobj);
    5.85 +	}
    5.86 +	return false;
    5.87 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/prototype/src/audio/sample.h	Sun Sep 16 08:16:50 2012 +0300
     6.3 @@ -0,0 +1,17 @@
     6.4 +#ifndef SAMPLE_H_
     6.5 +#define SAMPLE_H_
     6.6 +
     6.7 +class AudioSample {
     6.8 +private:
     6.9 +	unsigned int albuffer;
    6.10 +
    6.11 +	void destroy();
    6.12 +
    6.13 +public:
    6.14 +	AudioSample();
    6.15 +	~AudioSample();
    6.16 +
    6.17 +	bool load(const char *fname);
    6.18 +};
    6.19 +
    6.20 +#endif	// SAMPLE_H_
     7.1 --- a/prototype/src/cfg.cc	Thu Sep 13 06:33:51 2012 +0300
     7.2 +++ b/prototype/src/cfg.cc	Sun Sep 16 08:16:50 2012 +0300
     7.3 @@ -10,6 +10,7 @@
     7.4  	width = 800;
     7.5  	height = 600;
     7.6  	stereo = false;
     7.7 +	sound = true;
     7.8  	level_file = "0.level";
     7.9  	tileset_file = "default.tileset";
    7.10  	use_deferred = true;
    7.11 @@ -26,6 +27,8 @@
    7.12  				}
    7.13  			} else if(strcmp(argv[i], "-stereo") == 0) {
    7.14  				stereo = true;
    7.15 +			} else if(strcmp(argv[i], "-nosound") == 0) {
    7.16 +				sound = false;
    7.17  			} else if(strcmp(argv[i], "-level") == 0) {
    7.18  				level_file = argv[++i];
    7.19  			} else if(strcmp(argv[i], "-tileset") == 0) {
    7.20 @@ -38,6 +41,7 @@
    7.21  				printf("  -level <filename>   specify which level file to load\n");
    7.22  				printf("  -tileset <filename> specify which tileset to use\n");
    7.23  				printf("  -stereo             enable stereoscopic rendering\n");
    7.24 +				printf("  -nosound            disable sound output\n");
    7.25  				printf("  -no-deferred        disable deferred renderer\n");
    7.26  				printf("  -h/-help            print usage information and exit\n");
    7.27  				exit(0);
     8.1 --- a/prototype/src/cfg.h	Thu Sep 13 06:33:51 2012 +0300
     8.2 +++ b/prototype/src/cfg.h	Sun Sep 16 08:16:50 2012 +0300
     8.3 @@ -5,6 +5,7 @@
     8.4  public:
     8.5  	int width, height;
     8.6  	bool stereo;
     8.7 +	bool sound;
     8.8  	const char *level_file, *tileset_file;
     8.9  	bool use_deferred;
    8.10  
     9.1 --- a/prototype/src/main.cc	Thu Sep 13 06:33:51 2012 +0300
     9.2 +++ b/prototype/src/main.cc	Sun Sep 16 08:16:50 2012 +0300
     9.3 @@ -14,6 +14,7 @@
     9.4  #include "cmdcon.h"
     9.5  #include "cfg.h"
     9.6  #include "timer.h"
     9.7 +#include "audio.h"
     9.8  
     9.9  bool init(int xsz, int ysz);
    9.10  void cleanup();
    9.11 @@ -125,11 +126,20 @@
    9.12  
    9.13  	cam.input_move(0, 0.5, 0);
    9.14  
    9.15 +	if(cfg.sound && !init_audio()) {
    9.16 +		fprintf(stderr, "failed to initialize audio, continuing silently\n");
    9.17 +		cfg.sound = false;
    9.18 +	}
    9.19 +
    9.20  	return true;
    9.21  }
    9.22  
    9.23  void cleanup()
    9.24  {
    9.25 +	if(cfg.sound) {
    9.26 +		destroy_audio();
    9.27 +	}
    9.28 +
    9.29  	delete level;
    9.30  	delete tileset;
    9.31  	delete rend;