xref: /haiku/src/kits/midi/SoftSynth.cpp (revision 81f5654c124bf46fba0fd251f208e2d88d81e1ce)
1 /*
2  * Copyright (c) 2004 Matthijs Hollemans
3  * Copyright (c) 2003 Jerome Leveque
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <FindDirectory.h>
25 #include <Path.h>
26 #include <string.h>
27 #include <stdlib.h>
28 
29 #include "debug.h"
30 #include "SoftSynth.h"
31 
32 using namespace BPrivate;
33 
34 //------------------------------------------------------------------------------
35 
36 BSoftSynth::BSoftSynth()
37 {
38 	instrumentsFile = NULL;
39 	SetDefaultInstrumentsFile();
40 
41 	sampleRate = 22050;
42 	interpMode = B_LINEAR_INTERPOLATION;
43 	maxVoices = 28;
44 	limiterThreshold = 7;
45 	reverbEnabled = true;
46 	reverbMode = B_REVERB_BALLROOM;
47 	volumeScale = 1.0;
48 }
49 
50 //------------------------------------------------------------------------------
51 
52 BSoftSynth::~BSoftSynth()
53 {
54 	Unload();
55 }
56 
57 //------------------------------------------------------------------------------
58 
59 void BSoftSynth::Unload(void)
60 {
61 	/* TODO: purge samples from memory */
62 
63 	free(instrumentsFile);
64 	instrumentsFile = NULL;
65 }
66 
67 //------------------------------------------------------------------------------
68 
69 bool BSoftSynth::IsLoaded(void) const
70 {
71 	return instrumentsFile != NULL;
72 }
73 
74 //------------------------------------------------------------------------------
75 
76 status_t BSoftSynth::SetDefaultInstrumentsFile()
77 {
78 	BPath path;
79 	if (B_OK == find_directory(B_SYNTH_DIRECTORY, &path, false, NULL))
80 	{
81 		path.Append(B_BIG_SYNTH_FILE);
82 		return SetInstrumentsFile(path.Path());
83 	}
84 
85 	return B_ERROR;
86 }
87 
88 //------------------------------------------------------------------------------
89 
90 status_t BSoftSynth::SetInstrumentsFile(const char* path)
91 {
92 	if (path == NULL)
93 	{
94 		return B_BAD_VALUE;
95 	}
96 
97 	if (IsLoaded())
98 	{
99 		Unload();
100 	}
101 
102 	instrumentsFile = strdup(path);
103 	return B_OK;
104 }
105 
106 //------------------------------------------------------------------------------
107 
108 status_t BSoftSynth::LoadAllInstruments()
109 {
110 	/* TODO: Should load all of the instruments from the sample bank. */
111 
112 	UNIMPLEMENTED
113 	return B_OK;
114 }
115 
116 //------------------------------------------------------------------------------
117 
118 status_t BSoftSynth::LoadInstrument(int16 instrument)
119 {
120 	UNIMPLEMENTED
121 	return B_OK;
122 }
123 
124 //------------------------------------------------------------------------------
125 
126 status_t BSoftSynth::UnloadInstrument(int16 instrument)
127 {
128 	UNIMPLEMENTED
129 	return B_OK;
130 }
131 
132 //------------------------------------------------------------------------------
133 
134 status_t BSoftSynth::RemapInstrument(int16 from, int16 to)
135 {
136 	UNIMPLEMENTED
137 	return B_OK;
138 }
139 
140 //------------------------------------------------------------------------------
141 
142 void BSoftSynth::FlushInstrumentCache(bool startStopCache)
143 {
144 	// TODO: we may decide not to support this function because it's weird!
145 
146 	UNIMPLEMENTED
147 }
148 
149 //------------------------------------------------------------------------------
150 
151 void BSoftSynth::SetVolume(double volume)
152 {
153 	if (volume >= 0.0)
154 	{
155 		volumeScale = volume;
156 	}
157 }
158 
159 //------------------------------------------------------------------------------
160 
161 double BSoftSynth::Volume(void) const
162 {
163 	return volumeScale;
164 }
165 
166 //------------------------------------------------------------------------------
167 
168 status_t BSoftSynth::SetSamplingRate(int32 rate)
169 {
170 	// TODO: According to the BeBook, we should round rate to the nearest
171 	// acceptable value. However, this function may change depending on the
172 	// softsynth back-end we'll use.
173 
174 	if (rate == 11025 || rate == 22050 || rate == 44100)
175 	{
176 		sampleRate = rate;
177 		return B_OK;
178 	}
179 
180 	return B_BAD_VALUE;
181 }
182 
183 //------------------------------------------------------------------------------
184 
185 int32 BSoftSynth::SamplingRate() const
186 {
187 	return sampleRate;
188 }
189 
190 //------------------------------------------------------------------------------
191 
192 status_t BSoftSynth::SetInterpolation(interpolation_mode mode)
193 {
194 	// TODO: this function could change depending on the synth back-end.
195 
196 	interpMode = mode;
197 	return B_OK;
198 }
199 
200 //------------------------------------------------------------------------------
201 
202 interpolation_mode BSoftSynth::Interpolation() const
203 {
204 	return interpMode;
205 }
206 
207 //------------------------------------------------------------------------------
208 
209 status_t BSoftSynth::EnableReverb(bool enabled)
210 {
211 	reverbEnabled = enabled;
212 	return B_OK;
213 }
214 
215 //------------------------------------------------------------------------------
216 
217 bool BSoftSynth::IsReverbEnabled() const
218 {
219 	return reverbEnabled;
220 }
221 
222 //------------------------------------------------------------------------------
223 
224 void BSoftSynth::SetReverb(reverb_mode mode)
225 {
226 	// TODO: this function could change depending on the synth back-end.
227 
228 	reverbMode = mode;
229 }
230 
231 //------------------------------------------------------------------------------
232 
233 reverb_mode BSoftSynth::Reverb() const
234 {
235 	return reverbMode;
236 }
237 
238 //------------------------------------------------------------------------------
239 
240 status_t BSoftSynth::SetMaxVoices(int32 max)
241 {
242 	// TODO: this function could change depending on the synth back-end.
243 
244 	if (max > 0 && max <= 32)
245 	{
246 		maxVoices = max;
247 		return B_OK;
248 	}
249 
250 	return B_BAD_VALUE;
251 }
252 
253 //------------------------------------------------------------------------------
254 
255 int16 BSoftSynth::MaxVoices(void) const
256 {
257 	return maxVoices;
258 }
259 
260 //------------------------------------------------------------------------------
261 
262 status_t BSoftSynth::SetLimiterThreshold(int32 threshold)
263 {
264 	// TODO: this function could change depending on the synth back-end.
265 
266 	if (threshold > 0 && threshold <= 32)
267 	{
268 		limiterThreshold = threshold;
269 		return B_OK;
270 	}
271 
272 	return B_BAD_VALUE;
273 }
274 
275 //------------------------------------------------------------------------------
276 
277 int16 BSoftSynth::LimiterThreshold(void) const
278 {
279 	return limiterThreshold;
280 }
281 
282 //------------------------------------------------------------------------------
283 
284 void BSoftSynth::Pause(void)
285 {
286 	UNIMPLEMENTED
287 }
288 
289 //------------------------------------------------------------------------------
290 
291 void BSoftSynth::Resume(void)
292 {
293 	UNIMPLEMENTED
294 }
295 
296 //------------------------------------------------------------------------------
297 
298 void BSoftSynth::NoteOff(
299 	uchar channel, uchar note, uchar velocity, uint32 time)
300 {
301 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
302 	UNIMPLEMENTED
303 }
304 
305 //------------------------------------------------------------------------------
306 
307 void BSoftSynth::NoteOn(
308 	uchar channel, uchar note, uchar velocity, uint32 time)
309 {
310 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
311 	UNIMPLEMENTED
312 }
313 
314 //------------------------------------------------------------------------------
315 
316 void BSoftSynth::KeyPressure(
317 	uchar channel, uchar note, uchar pressure, uint32 time)
318 {
319 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
320 	UNIMPLEMENTED
321 }
322 
323 //------------------------------------------------------------------------------
324 
325 void BSoftSynth::ControlChange(
326 	uchar channel, uchar controlNumber, uchar controlValue, uint32 time)
327 {
328 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
329 	UNIMPLEMENTED
330 }
331 
332 //------------------------------------------------------------------------------
333 
334 void BSoftSynth::ProgramChange(
335 	uchar channel, uchar programNumber, uint32 time)
336 {
337 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
338 	UNIMPLEMENTED
339 }
340 
341 //------------------------------------------------------------------------------
342 
343 void BSoftSynth::ChannelPressure(uchar channel, uchar pressure, uint32 time)
344 {
345 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
346 	UNIMPLEMENTED
347 }
348 
349 //------------------------------------------------------------------------------
350 
351 void BSoftSynth::PitchBend(uchar channel, uchar lsb, uchar msb, uint32 time)
352 {
353 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
354 	UNIMPLEMENTED
355 }
356 
357 //------------------------------------------------------------------------------
358 
359 void BSoftSynth::SystemExclusive(void* data, size_t length, uint32 time)
360 {
361 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
362 	UNIMPLEMENTED
363 }
364 
365 //------------------------------------------------------------------------------
366 
367 void BSoftSynth::SystemCommon(
368 	uchar status, uchar data1, uchar data2, uint32 time)
369 {
370 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
371 	UNIMPLEMENTED
372 }
373 
374 //------------------------------------------------------------------------------
375 
376 void BSoftSynth::SystemRealTime(uchar status, uint32 time)
377 {
378 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
379 	UNIMPLEMENTED
380 }
381 
382 //------------------------------------------------------------------------------
383 
384 void BSoftSynth::TempoChange(int32 beatsPerMinute, uint32 time)
385 {
386 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
387 	UNIMPLEMENTED
388 }
389 
390 //------------------------------------------------------------------------------
391 
392 void BSoftSynth::AllNotesOff(bool justChannel, uint32 time)
393 {
394 	snooze_until(time * (bigtime_t) 1000, B_SYSTEM_TIMEBASE);
395 	UNIMPLEMENTED
396 }
397 
398 //------------------------------------------------------------------------------
399