1 /*  $Id: c-api.cpp,v 1.1 2012/07/08 00:46:01 sarrazip Exp $
2 
3     flatzebra - SDL-based sound renderer
4     Copyright (C) 2011 Pierre Sarrazin <http://sarrazip.com/>
5 
6     This program is free software; you can redistribute it and/or
7     modify it under the terms of the GNU General Public License
8     as published by the Free Software Foundation; either version 2
9     of the License, or (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public
17     License along with this program; if not, write to the Free
18     Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19     Boston, MA  02110-1301, USA.
20 */
21 
22 #include <roundbeetle/c-api.h>
23 
24 #include <roundbeetle/Engine.h>
25 #include <roundbeetle/SoundRenderer.h>
26 #include <roundbeetle/ADSR.h>
27 
28 #include <map>
29 #include <iostream>
30 
31 using namespace roundbeetle;
32 using namespace std;
33 
34 
35 typedef map<int, FrequencyFunction *> RequestMap;
36 
37 static RequestMap requestMap;
38 
39 
40 // This callback will be invoked under the renderer mutex.
41 //
42 static void
onRequestFinished(int reqHandle,void *)43 onRequestFinished(int reqHandle, void *)
44 {
45     RequestMap::iterator it = requestMap.find(reqHandle);
46     if (it == requestMap.end())
47         return;
48     assert(it->second != NULL);
49     //cout << "onRequestFinished(" << reqHandle << "): " << it->second << endl;
50     delete it->second;
51     requestMap.erase(it);
52 }
53 
54 
55 int
flatzebra_sound_create(int rendererFreq)56 flatzebra_sound_create(int rendererFreq)
57 {
58     int status = Engine::create(rendererFreq, 0, NULL);
59     if (status != 0)
60         return status;  // failure
61     Engine &engine = Engine::instance();
62     engine.registerRequestFinishedCallback(onRequestFinished, NULL);
63     engine.postBusInit();
64     return 0;
65 }
66 
67 
68 void
flatzebra_sound_destroy()69 flatzebra_sound_destroy()
70 {
71     Engine::destroy();
72 }
73 
74 
75 void
flatzebra_sound_setMasterVolume(float linVol)76 flatzebra_sound_setMasterVolume(float linVol)
77 {
78     SoundRenderer::instance().getTopFrameSourceAdder().setLinearAttenuation(linVol);
79 }
80 
81 
82 int
flatzebra_sound_requestSquareWave(float startFreq,float endFreq,float attackLevel,float sustainLevel,float attackTime,float decayTime,float sustainTime,float releaseTime,size_t loopCount)83 flatzebra_sound_requestSquareWave(float startFreq,
84                               float endFreq,
85                               float attackLevel,
86                               float sustainLevel,
87                               float attackTime,
88                               float decayTime,
89                               float sustainTime,
90                               float releaseTime,
91                               size_t loopCount)
92 {
93     ADSR adsr(attackLevel, sustainLevel,
94               attackTime, decayTime, sustainTime, releaseTime);
95 
96     LinearMovingFreq *ff = new LinearMovingFreq(startFreq, endFreq, adsr.getTotalTime());
97 
98     Engine &engine = Engine::instance();
99     Bus &mainBus = engine.getMainBus();
100     int reqHandle = engine.requestSquareWave(*ff, adsr, loopCount, mainBus);
101 
102     if (reqHandle == -1)  // if failed
103         delete ff;  // onRequestFinished() will not be invoked in this case
104     else
105         requestMap[reqHandle] = ff;
106 
107     return reqHandle;
108 }
109 
110 
111 #if 0
112 int
113 flatzebra_sound_setSquareWaveFreq(int sqWaveHandle, float newWaveFreq)
114 {
115     Engine &engine = Engine::instance();
116     return engine.setSquareWaveFreq(sqWaveHandle, newWaveFreq);
117 }
118 #endif
119 
120 
121 int
flatzebra_sound_requestWhiteNoise(float attackLevel,float sustainLevel,float attackTime,float decayTime,float sustainTime,float releaseTime,size_t loopCount)122 flatzebra_sound_requestWhiteNoise(float attackLevel,
123                               float sustainLevel,
124                               float attackTime,
125                               float decayTime,
126                               float sustainTime,
127                               float releaseTime,
128                               size_t loopCount)
129 {
130     Engine &engine = Engine::instance();
131     ADSR adsr(attackLevel, sustainLevel,
132               attackTime, decayTime, sustainTime, releaseTime);
133     Bus &mainBus = engine.getMainBus();
134     return engine.requestWhiteNoise(adsr, loopCount, mainBus);
135 }
136 
137 
138 int
flatzebra_sound_isRequestAlive(int reqHandle)139 flatzebra_sound_isRequestAlive(int reqHandle)
140 {
141     Engine &engine = Engine::instance();
142     return engine.isRequestAlive(reqHandle);
143 }
144 
145 
146 int
flatzebra_sound_pauseMainBus()147 flatzebra_sound_pauseMainBus()
148 {
149     Engine &engine = Engine::instance();
150     return engine.getMainBus().pause();
151 }
152 
153 
154 int
flatzebra_sound_resumeMainBus()155 flatzebra_sound_resumeMainBus()
156 {
157     Engine &engine = Engine::instance();
158     return engine.getMainBus().resume();
159 }
160