1 /* 2 * Copyright (c) 2004-2005 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 #ifndef _SOFT_SYNTH_H 25 #define _SOFT_SYNTH_H 26 27 /* 28 WORK IN PROGRESS! 29 30 This version of SoftSynth is a wrapper for Michael Pfeiffer's port 31 of TiMidity++ 2.11.3/3 (http://www.bebits.com/app/2736). 32 33 It works, but not good enough yet. Playback from MidiPlayer sounds 34 a lot worse than using TiMidity in standalone mode. Either TiMidity's 35 MidiConsumer doesn't work properly or the Midi Kit messes things up; 36 I haven't investigated yet. 37 38 To try it out, download TiMidity and the sound files (30MB): 39 http://bepdf.sourceforge.net/download/midi/TiMidity++-2.11.3_3.x86.zip 40 http://bepdf.sourceforge.net/download/midi/eawpats11_full_beos.zip 41 42 Follow the instructions in the archive to install. Then double-click 43 "Start TiMidity Server" to launch TiMidity. The server will publish a 44 consumer endpoint. You can verify this with PatchBay. 45 46 Build the Haiku Midi Kit. Put libmidi.so and libmidi2.so in ~/config/lib. 47 Quit the BeOS midi_server. Launch the Haiku midi_server. 48 49 Build the Haiku MidiPlayer (or use the BeOS MidiPlayer). Start it and 50 choose a MIDI file. If all went fine, you will hear TiMidity play back 51 the song. Just not very well. :-) 52 53 Note: You can still use the Midi Kit if you don't install TiMidity, 54 but the software synth will simply make no sound. 55 */ 56 57 #include <Midi.h> 58 #include <Synth.h> 59 60 class BMidiConsumer; 61 class BMidiLocalProducer; 62 class BMidiSynth; 63 class BSynth; 64 65 namespace BPrivate { 66 67 class BSoftSynth 68 { 69 public: 70 71 bool InitCheck(void) const; 72 73 void Unload(void); 74 bool IsLoaded(void) const; 75 76 status_t SetDefaultInstrumentsFile(); 77 status_t SetInstrumentsFile(const char* path); 78 79 status_t LoadAllInstruments(); 80 status_t LoadInstrument(int16 instrument); 81 status_t UnloadInstrument(int16 instrument); 82 status_t RemapInstrument(int16 from, int16 to); 83 void FlushInstrumentCache(bool startStopCache); 84 85 void SetVolume(double volume); 86 double Volume(void) const; 87 88 status_t SetSamplingRate(int32 rate); 89 int32 SamplingRate() const; 90 91 status_t SetInterpolation(interpolation_mode mode); 92 interpolation_mode Interpolation() const; 93 94 status_t EnableReverb(bool enabled); 95 bool IsReverbEnabled() const; 96 void SetReverb(reverb_mode mode); 97 reverb_mode Reverb() const; 98 99 status_t SetMaxVoices(int32 max); 100 int16 MaxVoices(void) const; 101 102 status_t SetLimiterThreshold(int32 threshold); 103 int16 LimiterThreshold(void) const; 104 105 void Pause(void); 106 void Resume(void); 107 108 void NoteOff(uchar, uchar, uchar, uint32); 109 void NoteOn(uchar, uchar, uchar, uint32); 110 void KeyPressure(uchar, uchar, uchar, uint32); 111 void ControlChange(uchar, uchar, uchar, uint32); 112 void ProgramChange(uchar, uchar, uint32); 113 void ChannelPressure(uchar, uchar, uint32); 114 void PitchBend(uchar, uchar, uchar, uint32); 115 void SystemExclusive(void*, size_t, uint32); 116 void SystemCommon(uchar, uchar, uchar, uint32); 117 void SystemRealTime(uchar, uint32); 118 void TempoChange(int32, uint32); 119 void AllNotesOff(bool, uint32); 120 121 private: 122 123 friend class ::BSynth; 124 friend class ::BMidiSynth; 125 126 BSoftSynth(); 127 ~BSoftSynth(); 128 129 void Init(); 130 void Done(); 131 132 bool initCheck; 133 char* instrumentsFile; 134 int32 sampleRate; 135 interpolation_mode interpMode; 136 int16 maxVoices; 137 int16 limiterThreshold; 138 reverb_mode reverbMode; 139 bool reverbEnabled; 140 double volumeScale; 141 142 /* 143 Note: Maybe this isn't the most efficient way to do things. 144 Now a producer connects to BMidiSynth, which is a consumer. 145 That consumer directly calls our NoteOff() etc, methods. 146 We create a new producer and connect it to TiMidity's consumer. 147 It would save some indirection if BMidiSynth's consumer would 148 be a proxy for TiMidity's. (I don't think that is possible, 149 because BMidiSynth is a BMidi object which always creates a 150 new consumer regardless. In any case, notes have to travel 151 a long way before they reach TiMidity. 152 */ 153 154 BMidiConsumer* consumer; 155 BMidiLocalProducer* producer; 156 }; 157 158 } // namespace BPrivate 159 160 #endif // _SYNTH_CONSUMER_H 161