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;