summary refs log tree commit diff stats
path: root/src/muxer.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2015-03-12 16:43:49 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2015-03-12 16:43:49 -0400
commit4c0869841d9ee6f8cc567b3e9eb2249193fc9f83 (patch)
treeff24074432b0178516bb7e2c43e87e8a9d72cadc /src/muxer.cpp
parent1a392a79b0491c5acc766705698191ed2ed6c2e6 (diff)
downloadtherapy-4c0869841d9ee6f8cc567b3e9eb2249193fc9f83.tar.gz
therapy-4c0869841d9ee6f8cc567b3e9eb2249193fc9f83.tar.bz2
therapy-4c0869841d9ee6f8cc567b3e9eb2249193fc9f83.zip
Play a sound when you jump
Diffstat (limited to 'src/muxer.cpp')
-rw-r--r--src/muxer.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/muxer.cpp b/src/muxer.cpp new file mode 100644 index 0000000..0844faa --- /dev/null +++ b/src/muxer.cpp
@@ -0,0 +1,111 @@
1#include "muxer.h"
2#include <cstdlib>
3#include <sndfile.h>
4#include <portaudio.h>
5#include <list>
6
7#define SAMPLE_RATE (44100)
8
9class Sound {
10 public:
11 Sound(const char* filename);
12 ~Sound();
13
14 float* ptr;
15 unsigned long pos;
16 unsigned long len;
17};
18
19struct Muxer {
20 std::list<Sound> playing;
21 PaStream* stream;
22};
23
24inline void dealWithPaError(PaError err)
25{
26 if (err != paNoError)
27 {
28 printf("PortAudio error: %s\n", Pa_GetErrorText(err));
29 exit(-1);
30 }
31}
32
33int paMuxerCallback(const void*, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void* userData)
34{
35 Muxer* muxer = (Muxer*) userData;
36 float* out = (float*) outputBuffer;
37
38 for (unsigned long i = 0; i<framesPerBuffer; i++)
39 {
40 unsigned long curAmount = 0;
41 *out = 0;
42
43 for (auto& sound : muxer->playing)
44 {
45 if (sound.pos < sound.len)
46 {
47 *out *= curAmount++;
48 *out += sound.ptr[sound.pos++];
49 *out /= (float) curAmount;
50 }
51 }
52
53 out++;
54 }
55
56 return 0;
57}
58
59static Muxer* muxer;
60
61void initMuxer()
62{
63 muxer = new Muxer();
64
65 dealWithPaError(Pa_Initialize());
66 dealWithPaError(Pa_OpenDefaultStream(&(muxer->stream), 0, 1, paFloat32, SAMPLE_RATE, paFramesPerBufferUnspecified, paMuxerCallback, muxer));
67 dealWithPaError(Pa_StartStream(muxer->stream));
68}
69
70void destroyMuxer()
71{
72 dealWithPaError(Pa_AbortStream(muxer->stream));
73 dealWithPaError(Pa_CloseStream(muxer->stream));
74 dealWithPaError(Pa_Terminate());
75
76 delete muxer;
77 muxer = 0;
78}
79
80void playSound(const char* filename)
81{
82 // First, clear out any sounds that have finished playing
83 muxer->playing.remove_if([] (Sound& value) { return value.pos >= value.len; });
84
85 // Then, add the new sound
86 muxer->playing.emplace_back(filename);
87}
88
89Sound::Sound(const char* filename)
90{
91 SF_INFO info;
92 SNDFILE* file = sf_open(filename, SFM_READ, &info);
93 if (file == nullptr)
94 {
95 printf("LibSndFile error: %s\n", sf_strerror(file));
96 exit(-1);
97 }
98
99 ptr = (float*) malloc(info.frames * info.channels * sizeof(float));
100 len = info.frames * info.channels;
101 pos = 0;
102
103 sf_readf_float(file, ptr, info.frames);
104
105 sf_close(file);
106}
107
108Sound::~Sound()
109{
110 free(ptr);
111}