# HG changeset patch # User John Tsiombikas # Date 1347772610 -10800 # Node ID d52711f2b9a17087a5d95669f5b4721d7a5a3ad0 # Parent f3030df271101df62233541c55ebfe253ff89d85 started writting audio code diff -r f3030df27110 -r d52711f2b9a1 prototype/Makefile.in --- a/prototype/Makefile.in Thu Sep 13 06:33:51 2012 +0300 +++ b/prototype/Makefile.in Sun Sep 16 08:16:50 2012 +0300 @@ -1,21 +1,29 @@ -csrc = $(wildcard src/*.c) $(wildcard vmath/*.c) $(wildcard drawtext/*.c) -ccsrc = $(wildcard src/*.cc) $(wildcard vmath/*.cc) +csrc = $(wildcard src/*.c) \ + $(wildcard vmath/*.c) \ + $(wildcard drawtext/*.c) + +ccsrc = $(wildcard src/*.cc) \ + $(wildcard src/audio/*.cc) \ + $(wildcard vmath/*.cc) + obj = $(csrc:.c=.o) $(ccsrc:.cc=.o) dep = $(obj:.o=.d) bin = proto warn = -Wall -Wno-format-extra-args -Wno-char-subscripts -inc = -I. -Ivmath -Idrawtext `pkg-config --cflags freetype2` +inc = -I. -Isrc/audio -Ivmath -Idrawtext `pkg-config --cflags freetype2` CFLAGS = -pedantic $(warn) $(dbg) $(opt) $(inc) CXXFLAGS = $(CFLAGS) $(cxx11_cflags) -LDFLAGS = $(cxx11_ldflags) $(libgl) -lm -lassimp -limago -lpsys `pkg-config --libs freetype2` +LDFLAGS = $(cxx11_ldflags) $(libgl) $(libal) -lvorbisfile -lm -lassimp -limago -lpsys `pkg-config --libs freetype2` ifeq ($(shell uname -s), Darwin) libgl = -framework OpenGL -framework GLUT -lglew + libal = -framework OpenAL else libgl = -lGL -lGLU -lglut -lGLEW + libal = -lopenal endif $(bin): $(obj) Makefile diff -r f3030df27110 -r d52711f2b9a1 prototype/src/audio/audio.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prototype/src/audio/audio.cc Sun Sep 16 08:16:50 2012 +0300 @@ -0,0 +1,44 @@ +#include +#include "openal.h" +#include "audio.h" + +#define CHECK_ERROR \ + do { \ + unsigned int err = alGetError(); \ + if(err != 0) { \ + fprintf(stderr, "%s:%d: AL error: %#x\n", __FILE__, __LINE__, err); \ + abort(); \ + } \ + } while(0) + +static ALCdevice *dev; +static ALCcontext *ctx; + + +bool init_audio() +{ + if(dev) { + return true; + } + + if(!(dev = alcOpenDevice(0))) { + fprintf(stderr, "failed to open OpenAL device\n"); + return false; + } + ctx = alcCreateContext(dev, 0); + alcMakeContextCurrent(ctx); + + alGetError(); // clear error code + return true; +} + +void destroy_audio() +{ + alcMakeContextCurrent(0); + if(ctx) { + alcDestroyContext(ctx); + } + if(dev) { + alcCloseDevice(dev); + } +} diff -r f3030df27110 -r d52711f2b9a1 prototype/src/audio/audio.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prototype/src/audio/audio.h Sun Sep 16 08:16:50 2012 +0300 @@ -0,0 +1,8 @@ +#ifndef AUDIO_H_ +#define AUDIO_H_ + +bool init_audio(); +void destroy_audio(); + + +#endif /* AUDIO_H_ */ diff -r f3030df27110 -r d52711f2b9a1 prototype/src/audio/openal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prototype/src/audio/openal.h Sun Sep 16 08:16:50 2012 +0300 @@ -0,0 +1,12 @@ +#ifndef OPENAL_H_ +#define OPENAL_H_ + +#ifndef __APPLE__ +#include +#include +#else +#include +#include +#endif + +#endif /* OPENAL_H_ */ diff -r f3030df27110 -r d52711f2b9a1 prototype/src/audio/sample.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prototype/src/audio/sample.cc Sun Sep 16 08:16:50 2012 +0300 @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include "openal.h" +#include "sample.h" + +AudioSample::AudioSample() +{ + albuffer = 0; +} + +AudioSample::~AudioSample() +{ + destroy(); +} + +void AudioSample::destroy() +{ + if(albuffer) { + alDeleteBuffers(1, &albuffer); + albuffer = 0; + } +} + +bool AudioSample::load(const char *fname) +{ + OggVorbis_File vf; + if(ov_fopen(fname, &vf) != 0) { + fprintf(stderr, "failed to open ogg/vorbis file: %s\n", fname); + return false; + } + vorbis_info *vinfo = ov_info(&vf, -1); + ALenum alfmt = vinfo->channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; + + printf("loading sample: %s: %ld samples/s, %s (%d chan)\n", fname, vinfo->rate, + vinfo->channels == 1 ? "mono" : "stereo", vinfo->channels); + + long num_samples = ov_pcm_total(&vf, -1); + int16_t *samples = new int16_t[num_samples]; + + long bufsz = num_samples * sizeof *samples; + long total_read = 0; + while(total_read < bufsz) { + int bitstream; + long rd = ov_read(&vf, (char*)samples + total_read, bufsz, 0, 2, 1, &bitstream); + if(!rd) { + bufsz = total_read; + printf("%s: unexpected eof while reading: %s\n", __FUNCTION__, fname); + } else { + total_read += rd; + } + } + + assert(alGetError() == AL_NO_ERROR); + + unsigned int bufobj = 0; + alGenBuffers(1, &bufobj); + if(alGetError()) { + fprintf(stderr, "failed to create OpenAL buffer\n"); + goto err; + } + + alBufferData(bufobj, alfmt, samples, bufsz, vinfo->rate); + if(alGetError()) { + fprintf(stderr, "failed to load sample data into OpenAL buffer: %u\n", bufobj); + goto err; + } + + ov_clear(&vf); + delete [] samples; + + destroy(); // cleanup previous buffer if any + albuffer = bufobj; + return true; + +err: + delete [] samples; + ov_clear(&vf); + if(bufobj) { + alDeleteBuffers(1, &bufobj); + } + return false; +} diff -r f3030df27110 -r d52711f2b9a1 prototype/src/audio/sample.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prototype/src/audio/sample.h Sun Sep 16 08:16:50 2012 +0300 @@ -0,0 +1,17 @@ +#ifndef SAMPLE_H_ +#define SAMPLE_H_ + +class AudioSample { +private: + unsigned int albuffer; + + void destroy(); + +public: + AudioSample(); + ~AudioSample(); + + bool load(const char *fname); +}; + +#endif // SAMPLE_H_ diff -r f3030df27110 -r d52711f2b9a1 prototype/src/cfg.cc --- a/prototype/src/cfg.cc Thu Sep 13 06:33:51 2012 +0300 +++ b/prototype/src/cfg.cc Sun Sep 16 08:16:50 2012 +0300 @@ -10,6 +10,7 @@ width = 800; height = 600; stereo = false; + sound = true; level_file = "0.level"; tileset_file = "default.tileset"; use_deferred = true; @@ -26,6 +27,8 @@ } } else if(strcmp(argv[i], "-stereo") == 0) { stereo = true; + } else if(strcmp(argv[i], "-nosound") == 0) { + sound = false; } else if(strcmp(argv[i], "-level") == 0) { level_file = argv[++i]; } else if(strcmp(argv[i], "-tileset") == 0) { @@ -38,6 +41,7 @@ printf(" -level specify which level file to load\n"); printf(" -tileset specify which tileset to use\n"); printf(" -stereo enable stereoscopic rendering\n"); + printf(" -nosound disable sound output\n"); printf(" -no-deferred disable deferred renderer\n"); printf(" -h/-help print usage information and exit\n"); exit(0); diff -r f3030df27110 -r d52711f2b9a1 prototype/src/cfg.h --- a/prototype/src/cfg.h Thu Sep 13 06:33:51 2012 +0300 +++ b/prototype/src/cfg.h Sun Sep 16 08:16:50 2012 +0300 @@ -5,6 +5,7 @@ public: int width, height; bool stereo; + bool sound; const char *level_file, *tileset_file; bool use_deferred; diff -r f3030df27110 -r d52711f2b9a1 prototype/src/main.cc --- a/prototype/src/main.cc Thu Sep 13 06:33:51 2012 +0300 +++ b/prototype/src/main.cc Sun Sep 16 08:16:50 2012 +0300 @@ -14,6 +14,7 @@ #include "cmdcon.h" #include "cfg.h" #include "timer.h" +#include "audio.h" bool init(int xsz, int ysz); void cleanup(); @@ -125,11 +126,20 @@ cam.input_move(0, 0.5, 0); + if(cfg.sound && !init_audio()) { + fprintf(stderr, "failed to initialize audio, continuing silently\n"); + cfg.sound = false; + } + return true; } void cleanup() { + if(cfg.sound) { + destroy_audio(); + } + delete level; delete tileset; delete rend;