1fbaf754aSmahlzeit /* 2d1c4420eSmahlzeit * Copyright (c) 2004-2005 Matthijs Hollemans 3fbaf754aSmahlzeit * Copyright (c) 2003 Jerome Leveque 4fbaf754aSmahlzeit * 5fbaf754aSmahlzeit * Permission is hereby granted, free of charge, to any person obtaining a 6fbaf754aSmahlzeit * copy of this software and associated documentation files (the "Software"), 7fbaf754aSmahlzeit * to deal in the Software without restriction, including without limitation 8fbaf754aSmahlzeit * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9fbaf754aSmahlzeit * and/or sell copies of the Software, and to permit persons to whom the 10fbaf754aSmahlzeit * Software is furnished to do so, subject to the following conditions: 11fbaf754aSmahlzeit * 12fbaf754aSmahlzeit * The above copyright notice and this permission notice shall be included in 13fbaf754aSmahlzeit * all copies or substantial portions of the Software. 14fbaf754aSmahlzeit * 15fbaf754aSmahlzeit * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16fbaf754aSmahlzeit * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17fbaf754aSmahlzeit * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18fbaf754aSmahlzeit * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19fbaf754aSmahlzeit * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20fbaf754aSmahlzeit * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21fbaf754aSmahlzeit * DEALINGS IN THE SOFTWARE. 22fbaf754aSmahlzeit */ 23fbaf754aSmahlzeit 24fbaf754aSmahlzeit #ifndef _SOFT_SYNTH_H 25fbaf754aSmahlzeit #define _SOFT_SYNTH_H 26fbaf754aSmahlzeit 27d1c4420eSmahlzeit /* 28d1c4420eSmahlzeit WORK IN PROGRESS! 29d1c4420eSmahlzeit 30d1c4420eSmahlzeit This version of SoftSynth is a wrapper for Michael Pfeiffer's port 31d1c4420eSmahlzeit of TiMidity++ 2.11.3/3 (http://www.bebits.com/app/2736). 32d1c4420eSmahlzeit 33d1c4420eSmahlzeit It works, but not good enough yet. Playback from MidiPlayer sounds 34d1c4420eSmahlzeit a lot worse than using TiMidity in standalone mode. Either TiMidity's 35d1c4420eSmahlzeit MidiConsumer doesn't work properly or the Midi Kit messes things up; 36d1c4420eSmahlzeit I haven't investigated yet. 37d1c4420eSmahlzeit 38d1c4420eSmahlzeit To try it out, download TiMidity and the sound files (30MB): 39d1c4420eSmahlzeit http://bepdf.sourceforge.net/download/midi/TiMidity++-2.11.3_3.x86.zip 40d1c4420eSmahlzeit http://bepdf.sourceforge.net/download/midi/eawpats11_full_beos.zip 41d1c4420eSmahlzeit 42d1c4420eSmahlzeit Follow the instructions in the archive to install. Then double-click 43d1c4420eSmahlzeit "Start TiMidity Server" to launch TiMidity. The server will publish a 44d1c4420eSmahlzeit consumer endpoint. You can verify this with PatchBay. 45d1c4420eSmahlzeit 46d1c4420eSmahlzeit Build the Haiku Midi Kit. Put libmidi.so and libmidi2.so in ~/config/lib. 47d1c4420eSmahlzeit Quit the BeOS midi_server. Launch the Haiku midi_server. 48d1c4420eSmahlzeit 49d1c4420eSmahlzeit Build the Haiku MidiPlayer (or use the BeOS MidiPlayer). Start it and 50d1c4420eSmahlzeit choose a MIDI file. If all went fine, you will hear TiMidity play back 51d1c4420eSmahlzeit the song. Just not very well. :-) 52d1c4420eSmahlzeit 53d1c4420eSmahlzeit Note: You can still use the Midi Kit if you don't install TiMidity, 54d1c4420eSmahlzeit but the software synth will simply make no sound. 55d1c4420eSmahlzeit */ 56d1c4420eSmahlzeit 57fbaf754aSmahlzeit #include <Midi.h> 58fbaf754aSmahlzeit #include <Synth.h> 59fbaf754aSmahlzeit 60d1c4420eSmahlzeit class BMidiConsumer; 61d1c4420eSmahlzeit class BMidiLocalProducer; 62*65f512e0SIngo Weinhold class BMidiSynth; 63*65f512e0SIngo Weinhold class BSynth; 64d1c4420eSmahlzeit 65fbaf754aSmahlzeit namespace BPrivate { 66fbaf754aSmahlzeit 67fbaf754aSmahlzeit class BSoftSynth 68fbaf754aSmahlzeit { 69fbaf754aSmahlzeit public: 70fbaf754aSmahlzeit 71d1c4420eSmahlzeit bool InitCheck(void) const; 72d1c4420eSmahlzeit 73fbaf754aSmahlzeit void Unload(void); 74fbaf754aSmahlzeit bool IsLoaded(void) const; 75fbaf754aSmahlzeit 76fbaf754aSmahlzeit status_t SetDefaultInstrumentsFile(); 77fbaf754aSmahlzeit status_t SetInstrumentsFile(const char* path); 78fbaf754aSmahlzeit 79fbaf754aSmahlzeit status_t LoadAllInstruments(); 80fbaf754aSmahlzeit status_t LoadInstrument(int16 instrument); 81fbaf754aSmahlzeit status_t UnloadInstrument(int16 instrument); 82fbaf754aSmahlzeit status_t RemapInstrument(int16 from, int16 to); 83fbaf754aSmahlzeit void FlushInstrumentCache(bool startStopCache); 84fbaf754aSmahlzeit 85fbaf754aSmahlzeit void SetVolume(double volume); 86fbaf754aSmahlzeit double Volume(void) const; 87fbaf754aSmahlzeit 88fbaf754aSmahlzeit status_t SetSamplingRate(int32 rate); 89fbaf754aSmahlzeit int32 SamplingRate() const; 90fbaf754aSmahlzeit 91fbaf754aSmahlzeit status_t SetInterpolation(interpolation_mode mode); 92fbaf754aSmahlzeit interpolation_mode Interpolation() const; 93fbaf754aSmahlzeit 94fbaf754aSmahlzeit status_t EnableReverb(bool enabled); 95fbaf754aSmahlzeit bool IsReverbEnabled() const; 96fbaf754aSmahlzeit void SetReverb(reverb_mode mode); 97fbaf754aSmahlzeit reverb_mode Reverb() const; 98fbaf754aSmahlzeit 99fbaf754aSmahlzeit status_t SetMaxVoices(int32 max); 100fbaf754aSmahlzeit int16 MaxVoices(void) const; 101fbaf754aSmahlzeit 102fbaf754aSmahlzeit status_t SetLimiterThreshold(int32 threshold); 103fbaf754aSmahlzeit int16 LimiterThreshold(void) const; 104fbaf754aSmahlzeit 105fbaf754aSmahlzeit void Pause(void); 106fbaf754aSmahlzeit void Resume(void); 107fbaf754aSmahlzeit 108fbaf754aSmahlzeit void NoteOff(uchar, uchar, uchar, uint32); 109fbaf754aSmahlzeit void NoteOn(uchar, uchar, uchar, uint32); 110fbaf754aSmahlzeit void KeyPressure(uchar, uchar, uchar, uint32); 111fbaf754aSmahlzeit void ControlChange(uchar, uchar, uchar, uint32); 112fbaf754aSmahlzeit void ProgramChange(uchar, uchar, uint32); 113fbaf754aSmahlzeit void ChannelPressure(uchar, uchar, uint32); 114fbaf754aSmahlzeit void PitchBend(uchar, uchar, uchar, uint32); 115fbaf754aSmahlzeit void SystemExclusive(void*, size_t, uint32); 116fbaf754aSmahlzeit void SystemCommon(uchar, uchar, uchar, uint32); 117fbaf754aSmahlzeit void SystemRealTime(uchar, uint32); 118fbaf754aSmahlzeit void TempoChange(int32, uint32); 119fbaf754aSmahlzeit void AllNotesOff(bool, uint32); 120fbaf754aSmahlzeit 121fbaf754aSmahlzeit private: 122fbaf754aSmahlzeit 123*65f512e0SIngo Weinhold friend class ::BSynth; 124*65f512e0SIngo Weinhold friend class ::BMidiSynth; 125fbaf754aSmahlzeit 126fbaf754aSmahlzeit BSoftSynth(); 127fbaf754aSmahlzeit ~BSoftSynth(); 128fbaf754aSmahlzeit 129d1c4420eSmahlzeit void Init(); 130d1c4420eSmahlzeit void Done(); 131d1c4420eSmahlzeit 132d1c4420eSmahlzeit bool initCheck; 133fbaf754aSmahlzeit char* instrumentsFile; 134fbaf754aSmahlzeit int32 sampleRate; 135fbaf754aSmahlzeit interpolation_mode interpMode; 136fbaf754aSmahlzeit int16 maxVoices; 137fbaf754aSmahlzeit int16 limiterThreshold; 138fbaf754aSmahlzeit reverb_mode reverbMode; 139fbaf754aSmahlzeit bool reverbEnabled; 140fbaf754aSmahlzeit double volumeScale; 141d1c4420eSmahlzeit 142d1c4420eSmahlzeit /* 143d1c4420eSmahlzeit Note: Maybe this isn't the most efficient way to do things. 144d1c4420eSmahlzeit Now a producer connects to BMidiSynth, which is a consumer. 145d1c4420eSmahlzeit That consumer directly calls our NoteOff() etc, methods. 146d1c4420eSmahlzeit We create a new producer and connect it to TiMidity's consumer. 147d1c4420eSmahlzeit It would save some indirection if BMidiSynth's consumer would 148d1c4420eSmahlzeit be a proxy for TiMidity's. (I don't think that is possible, 149d1c4420eSmahlzeit because BMidiSynth is a BMidi object which always creates a 150d1c4420eSmahlzeit new consumer regardless. In any case, notes have to travel 151d1c4420eSmahlzeit a long way before they reach TiMidity. 152d1c4420eSmahlzeit */ 153d1c4420eSmahlzeit 154d1c4420eSmahlzeit BMidiConsumer* consumer; 155d1c4420eSmahlzeit BMidiLocalProducer* producer; 156fbaf754aSmahlzeit }; 157fbaf754aSmahlzeit 158fbaf754aSmahlzeit } // namespace BPrivate 159fbaf754aSmahlzeit 160fbaf754aSmahlzeit #endif // _SYNTH_CONSUMER_H 161