diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/muxer.cpp | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/src/muxer.cpp b/src/muxer.cpp index d831e6d..ecce82b 100644 --- a/src/muxer.cpp +++ b/src/muxer.cpp | |||
@@ -4,6 +4,9 @@ | |||
4 | #include <portaudio.h> | 4 | #include <portaudio.h> |
5 | #include <list> | 5 | #include <list> |
6 | #include <cmath> | 6 | #include <cmath> |
7 | #include <vector> | ||
8 | #include <stdexcept> | ||
9 | #include <sstream> | ||
7 | 10 | ||
8 | #define SAMPLE_RATE (44100) | 11 | #define SAMPLE_RATE (44100) |
9 | #define DELAY_IN_SECS (0.075) | 12 | #define DELAY_IN_SECS (0.075) |
@@ -17,11 +20,14 @@ const int delaySize = SAMPLE_RATE * DELAY_IN_SECS; | |||
17 | class Sound { | 20 | class Sound { |
18 | public: | 21 | public: |
19 | Sound(const char* filename, float vol); | 22 | Sound(const char* filename, float vol); |
20 | ~Sound(); | 23 | |
21 | 24 | inline bool isDone() const | |
22 | float* ptr; | 25 | { |
26 | return pos >= data.size(); | ||
27 | } | ||
28 | |||
29 | std::vector<float> data; | ||
23 | unsigned long pos; | 30 | unsigned long pos; |
24 | unsigned long len; | ||
25 | float vol; | 31 | float vol; |
26 | }; | 32 | }; |
27 | 33 | ||
@@ -45,29 +51,29 @@ int paMuxerCallback(const void*, void* outputBuffer, unsigned long framesPerBuff | |||
45 | { | 51 | { |
46 | Muxer* muxer = (Muxer*) userData; | 52 | Muxer* muxer = (Muxer*) userData; |
47 | float* out = (float*) outputBuffer; | 53 | float* out = (float*) outputBuffer; |
48 | 54 | ||
49 | for (unsigned long i = 0; i<framesPerBuffer; i++) | 55 | for (unsigned long i = 0; i<framesPerBuffer; i++) |
50 | { | 56 | { |
51 | float in = 0.0; | 57 | float in = 0.0; |
52 | 58 | ||
53 | for (auto& sound : muxer->playing) | 59 | for (auto& sound : muxer->playing) |
54 | { | 60 | { |
55 | if (sound.pos < sound.len) | 61 | if (sound.pos < sound.data.size()) |
56 | { | 62 | { |
57 | in += sound.ptr[sound.pos++] * sound.vol; | 63 | in += sound.data[sound.pos++] * sound.vol; |
58 | } | 64 | } |
59 | } | 65 | } |
60 | 66 | ||
61 | if (in > 1) in = 1; | 67 | if (in > 1) in = 1; |
62 | if (in < -1) in = -1; | 68 | if (in < -1) in = -1; |
63 | 69 | ||
64 | float sample = muxer->delay[muxer->delayPos] * GAIN; | 70 | float sample = muxer->delay[muxer->delayPos] * GAIN; |
65 | muxer->delay[muxer->delayPos] = in + (muxer->delay[muxer->delayPos] * FEEDBACK); | 71 | muxer->delay[muxer->delayPos] = in + (muxer->delay[muxer->delayPos] * FEEDBACK); |
66 | muxer->delayPos++; | 72 | muxer->delayPos++; |
67 | if (muxer->delayPos > delaySize) muxer->delayPos = 0; | 73 | if (muxer->delayPos > delaySize) muxer->delayPos = 0; |
68 | *out++ = (in * DRY) + (sample * WET); | 74 | *out++ = (in * DRY) + (sample * WET); |
69 | } | 75 | } |
70 | 76 | ||
71 | return 0; | 77 | return 0; |
72 | } | 78 | } |
73 | 79 | ||
@@ -76,11 +82,11 @@ static Muxer* muxer; | |||
76 | void initMuxer() | 82 | void initMuxer() |
77 | { | 83 | { |
78 | muxer = new Muxer(); | 84 | muxer = new Muxer(); |
79 | 85 | ||
80 | dealWithPaError(Pa_Initialize()); | 86 | dealWithPaError(Pa_Initialize()); |
81 | dealWithPaError(Pa_OpenDefaultStream(&muxer->stream, 0, 1, paFloat32, SAMPLE_RATE, paFramesPerBufferUnspecified, paMuxerCallback, muxer)); | 87 | dealWithPaError(Pa_OpenDefaultStream(&muxer->stream, 0, 1, paFloat32, SAMPLE_RATE, paFramesPerBufferUnspecified, paMuxerCallback, muxer)); |
82 | dealWithPaError(Pa_StartStream(muxer->stream)); | 88 | dealWithPaError(Pa_StartStream(muxer->stream)); |
83 | 89 | ||
84 | muxer->delay = (float*) calloc(delaySize, sizeof(float)); | 90 | muxer->delay = (float*) calloc(delaySize, sizeof(float)); |
85 | } | 91 | } |
86 | 92 | ||
@@ -89,7 +95,7 @@ void destroyMuxer() | |||
89 | dealWithPaError(Pa_AbortStream(muxer->stream)); | 95 | dealWithPaError(Pa_AbortStream(muxer->stream)); |
90 | dealWithPaError(Pa_CloseStream(muxer->stream)); | 96 | dealWithPaError(Pa_CloseStream(muxer->stream)); |
91 | dealWithPaError(Pa_Terminate()); | 97 | dealWithPaError(Pa_Terminate()); |
92 | 98 | ||
93 | free(muxer->delay); | 99 | free(muxer->delay); |
94 | delete muxer; | 100 | delete muxer; |
95 | muxer = 0; | 101 | muxer = 0; |
@@ -98,8 +104,8 @@ void destroyMuxer() | |||
98 | void playSound(const char* filename, float vol) | 104 | void playSound(const char* filename, float vol) |
99 | { | 105 | { |
100 | // First, clear out any sounds that have finished playing | 106 | // First, clear out any sounds that have finished playing |
101 | muxer->playing.remove_if([] (Sound& value) { return value.pos >= value.len; }); | 107 | muxer->playing.remove_if([] (Sound& value) { return value.isDone(); }); |
102 | 108 | ||
103 | // Then, add the new sound | 109 | // Then, add the new sound |
104 | muxer->playing.emplace_back(filename, vol); | 110 | muxer->playing.emplace_back(filename, vol); |
105 | } | 111 | } |
@@ -110,21 +116,18 @@ Sound::Sound(const char* filename, float vol) | |||
110 | SNDFILE* file = sf_open(filename, SFM_READ, &info); | 116 | SNDFILE* file = sf_open(filename, SFM_READ, &info); |
111 | if (file == nullptr) | 117 | if (file == nullptr) |
112 | { | 118 | { |
113 | printf("LibSndFile error: %s\n", sf_strerror(file)); | 119 | std::ostringstream errmsg; |
114 | exit(-1); | 120 | errmsg << "LibSndFile error: "; |
121 | errmsg << sf_strerror(file); | ||
122 | |||
123 | throw std::logic_error(errmsg.str()); | ||
115 | } | 124 | } |
116 | 125 | ||
117 | ptr = (float*) malloc(info.frames * info.channels * sizeof(float)); | 126 | data.resize(info.frames * info.channels); |
118 | len = info.frames * info.channels; | ||
119 | pos = 0; | 127 | pos = 0; |
120 | this->vol = vol; | 128 | this->vol = vol; |
121 | |||
122 | sf_readf_float(file, ptr, info.frames); | ||
123 | |||
124 | sf_close(file); | ||
125 | } | ||
126 | 129 | ||
127 | Sound::~Sound() | 130 | sf_readf_float(file, data.data(), info.frames); |
128 | { | 131 | |
129 | free(ptr); | 132 | sf_close(file); |
130 | } | 133 | } |