From 281d46c3b45d170a3cff0470cbcb1be8911fa181 Mon Sep 17 00:00:00 2001
From: Pete Goodeve <pete.goodeve@computer.org>
Date: Sun, 11 Aug 2013 22:17:15 -0700
Subject: [PATCH] BSynth upgrade: synth.sf2 search, Reverb, and GetAudio
---
headers/os/midi/MidiDefs.h | 6 ++--
src/kits/midi/SoftSynth.cpp | 70 +++++++++++++++++++++++++++++++++++++++----
src/kits/midi/SoftSynth.h | 7 ++++-
src/kits/midi/Synth.cpp | 20 +++++++++----
4 files changed, 89 insertions(+), 14 deletions(-)
diff --git a/headers/os/midi/MidiDefs.h b/headers/os/midi/MidiDefs.h
index a4d44c5..10cd0f4 100644
a
|
b
|
|
13 | 13 | //------------------------------------------------------------------------------ |
14 | 14 | |
15 | 15 | /* Synthesizer things */ |
16 | | |
17 | | #define B_SYNTH_DIRECTORY B_SYSTEM_DATA_DIRECTORY |
| 16 | #define B_SYNTH_DIRECTORY B_COMMON_DATA_DIRECTORY |
| 17 | #define B_SYNTH_FILE "synth/synth.sf2" |
| 18 | /* Deprecated BeOS-era naming: */ |
| 19 | #define B_OLD_SYNTH_DIRECTORY B_SYSTEM_DATA_DIRECTORY |
18 | 20 | #define B_BIG_SYNTH_FILE "synth/big_synth.sy" |
19 | 21 | #define B_LITTLE_SYNTH_FILE "synth/little_synth.sy" |
20 | 22 | |
diff --git a/src/kits/midi/SoftSynth.cpp b/src/kits/midi/SoftSynth.cpp
index 9bcc757..881c005 100644
a
|
b
|
|
1 | 1 | /* |
2 | | * Copyright 2006, Haiku. |
| 2 | * Copyright 2006-2013, Haiku. |
3 | 3 | * |
4 | 4 | * Copyright (c) 2004-2005 Matthijs Hollemans |
5 | 5 | * Copyright (c) 2003 Jerome Leveque |
… |
… |
|
9 | 9 | * Jérôme Duval |
10 | 10 | * Jérôme Leveque |
11 | 11 | * Matthijs Hollemans |
| 12 | * Pete Goodeve |
12 | 13 | */ |
13 | 14 | |
14 | 15 | #include <MidiRoster.h> |
15 | 16 | #include <MidiConsumer.h> |
| 17 | #include <File.h> |
16 | 18 | #include <FindDirectory.h> |
17 | 19 | #include <Path.h> |
18 | 20 | #include <string.h> |
… |
… |
BSoftSynth::BSoftSynth()
|
29 | 31 | : fInitCheck(false), |
30 | 32 | fSynth(NULL), |
31 | 33 | fSettings(NULL), |
| 34 | fMonitor(NULL), |
| 35 | fMonitorSize(0), |
32 | 36 | fSoundPlayer(NULL) |
33 | 37 | { |
34 | 38 | fInstrumentsFile = NULL; |
… |
… |
BSoftSynth::~BSoftSynth()
|
52 | 56 | // didn't release our endpoints. |
53 | 57 | |
54 | 58 | Unload(); |
| 59 | delete fMonitor; |
55 | 60 | } |
56 | 61 | |
57 | 62 | |
… |
… |
status_t
|
84 | 89 | BSoftSynth::SetDefaultInstrumentsFile() |
85 | 90 | { |
86 | 91 | BPath path; |
87 | | if (B_OK == find_directory(B_SYNTH_DIRECTORY, &path, false, NULL)) { |
| 92 | status_t res = B_ERROR; |
| 93 | |
| 94 | // Look for user specified SoundFont first: |
| 95 | if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, false, NULL) == B_OK) { |
| 96 | path.Append(B_SYNTH_FILE); |
| 97 | res = SetInstrumentsFile(path.Path()); |
| 98 | } |
| 99 | |
| 100 | // Otherwise check for defaults: |
| 101 | if (res != B_OK && find_directory(B_USER_DATA_DIRECTORY, &path, false, NULL) == B_OK) { |
| 102 | path.Append(B_SYNTH_FILE); |
| 103 | res = SetInstrumentsFile(path.Path()); |
| 104 | } |
| 105 | |
| 106 | if (res != B_OK && find_directory(B_SYNTH_DIRECTORY, &path, false, NULL) == B_OK) { |
| 107 | path.Append(B_SYNTH_FILE); |
| 108 | res = SetInstrumentsFile(path.Path()); |
| 109 | } |
| 110 | |
| 111 | // If nothing else, try old naming convention: |
| 112 | if (res != B_OK && find_directory(B_SYSTEM_DATA_DIRECTORY, &path, false, NULL) == B_OK) { |
88 | 113 | path.Append(B_BIG_SYNTH_FILE); |
89 | | return SetInstrumentsFile(path.Path()); |
| 114 | res = SetInstrumentsFile(path.Path()); |
90 | 115 | } |
91 | 116 | |
92 | | return B_ERROR; |
| 117 | if (res != B_OK) |
| 118 | fprintf(stderr, "No Soundfont found\n"); |
| 119 | |
| 120 | return res; |
93 | 121 | } |
94 | 122 | |
95 | 123 | |
… |
… |
BSoftSynth::SetInstrumentsFile(const char* path)
|
98 | 126 | { |
99 | 127 | if (path == NULL) |
100 | 128 | return B_BAD_VALUE; |
| 129 | BFile test; |
| 130 | status_t res = test.SetTo(path, B_READ_ONLY); |
| 131 | if (res != B_OK) |
| 132 | return res; |
101 | 133 | |
102 | 134 | if (IsLoaded()) |
103 | 135 | Unload(); |
… |
… |
BSoftSynth::IsReverbEnabled() const
|
216 | 248 | } |
217 | 249 | |
218 | 250 | |
| 251 | struct ReverbSettings { |
| 252 | double room, damp, width, level; |
| 253 | } gReverbSettings[] = { |
| 254 | {0.0, 0.0, 0.0, 0.0}, // Dummy (table starts at 1) |
| 255 | {0.0, 0.0, 0.0, 0.0}, // B_REVERB_NONE |
| 256 | {0.2, 0.0, 0.5, 0.9}, // B_REVERB_CLOSET |
| 257 | {0.5, 0.0, 0.9, 0.9}, // B_REVERB_GARAGE |
| 258 | {0.7, 0.25, 0.9, 0.95}, // B_REVERB_BALLROOM |
| 259 | {0.99, 0.3, 1.0, 1.0}, // B_REVERB_CAVERN |
| 260 | {1.03, 0.6, 1.0, 1.0} // B_REVERB_DUNGEON |
| 261 | }; |
| 262 | |
| 263 | |
219 | 264 | void |
220 | 265 | BSoftSynth::SetReverb(reverb_mode mode) |
221 | 266 | { |
222 | | // TODO: this function could change depending on the synth back-end. |
223 | | |
| 267 | if (mode < B_REVERB_NONE || mode > B_REVERB_DUNGEON) |
| 268 | return; |
224 | 269 | fReverbMode = mode; |
| 270 | if (fSynth) { |
| 271 | ReverbSettings *rvb = &gReverbSettings[mode]; |
| 272 | fluid_synth_set_reverb(fSynth, rvb->room, rvb->damp, rvb->width, rvb->level); |
| 273 | } |
225 | 274 | } |
226 | 275 | |
227 | 276 | |
… |
… |
BSoftSynth::_Init()
|
444 | 493 | fprintf(stderr, "error in fluid_synth_sfload\n"); |
445 | 494 | return; |
446 | 495 | } |
| 496 | |
| 497 | SetReverb(fReverbMode); |
447 | 498 | |
448 | 499 | media_raw_audio_format format = media_raw_audio_format::wildcard; |
449 | 500 | format.channel_count = 2; |
… |
… |
BSoftSynth::PlayBuffer(void * cookie, void * data, size_t size, const media_raw_
|
491 | 542 | |
492 | 543 | // we use float samples |
493 | 544 | |
| 545 | if (synth->fMonitorSize == 0) { |
| 546 | synth->fMonitor = (float *)new void *[size]; |
| 547 | synth->fMonitorSize = size; |
| 548 | synth->fMonitorChans = format.channel_count; |
| 549 | } |
| 550 | |
494 | 551 | if (synth->fSynth) |
495 | 552 | fluid_synth_write_float(synth->fSynth, size / sizeof(float) / format.channel_count, |
496 | 553 | data, 0, format.channel_count, |
497 | 554 | data, 1, format.channel_count); |
| 555 | memcpy(synth->fMonitor, data, size); |
498 | 556 | } |
499 | 557 | |
diff --git a/src/kits/midi/SoftSynth.h b/src/kits/midi/SoftSynth.h
index 1e162d3..8de5a82 100644
a
|
b
|
|
1 | 1 | /* |
2 | | * Copyright 2006, Haiku. |
| 2 | * Copyright 2006-2013, Haiku. |
3 | 3 | * |
4 | 4 | * Copyright (c) 2004-2005 Matthijs Hollemans |
5 | 5 | * Copyright (c) 2003 Jerome Leveque |
… |
… |
|
9 | 9 | * Jérôme Duval |
10 | 10 | * Jérôme Leveque |
11 | 11 | * Matthijs Hollemans |
| 12 | * Pete Goodeve |
12 | 13 | */ |
13 | 14 | |
14 | 15 | #ifndef _SOFT_SYNTH_H |
… |
… |
private:
|
106 | 107 | |
107 | 108 | fluid_synth_t *fSynth; |
108 | 109 | fluid_settings_t* fSettings; |
| 110 | |
| 111 | float *fMonitor; |
| 112 | size_t fMonitorSize; |
| 113 | int16 fMonitorChans; |
109 | 114 | |
110 | 115 | BSoundPlayer *fSoundPlayer; |
111 | 116 | }; |
diff --git a/src/kits/midi/Synth.cpp b/src/kits/midi/Synth.cpp
index 8f64d9f..b7d8c0b 100644
a
|
b
|
|
1 | 1 | /* |
2 | | * Copyright 2006, Haiku. |
| 2 | * Copyright 2006-2013, Haiku. |
3 | 3 | * |
4 | 4 | * Copyright (c) 2002-2004 Matthijs Hollemans |
5 | 5 | * Copyright (c) 2003 Jerome Leveque |
… |
… |
|
8 | 8 | * Authors: |
9 | 9 | * Jérôme Leveque |
10 | 10 | * Matthijs Hollemans |
| 11 | * Pete Goodeve |
11 | 12 | */ |
12 | 13 | |
13 | 14 | #include <string.h> |
… |
… |
BSynth::SampleVolume(void) const
|
218 | 219 | status_t |
219 | 220 | BSynth::GetAudio(int16* pLeft, int16* pRight, int32 max_samples) const |
220 | 221 | { |
221 | | // We don't print a "not supported" message here. That would cause |
222 | | // significant slowdowns because applications ask for this many times. |
223 | | |
| 222 | if (fSynth->fMonitorSize > 0) { |
| 223 | int32 nSamples = fSynth->fMonitorSize / sizeof(float) / fSynth->fMonitorChans; |
| 224 | if (nSamples > max_samples) |
| 225 | nSamples = max_samples; |
| 226 | float *sPtr = fSynth->fMonitor; |
| 227 | for (int32 i = 0; i < nSamples; i++, sPtr += fSynth->fMonitorChans) { |
| 228 | *pLeft++ = (int16)(*sPtr * 32768); |
| 229 | *pRight++ = (int16)(*(sPtr+1) * 32768); |
| 230 | } |
| 231 | return nSamples; |
| 232 | } |
| 233 | |
| 234 | // Just in case there's no data: |
224 | 235 | memset(pLeft, 0, max_samples * sizeof(int16)); |
225 | 236 | memset(pRight, 0, max_samples * sizeof(int16)); |
226 | | |
227 | 237 | return max_samples; |
228 | 238 | } |
229 | 239 | |