xref: /haiku/src/kits/midi/SoftSynth.h (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
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 
63 namespace BPrivate {
64 
65 class BSoftSynth
66 {
67 public:
68 
69 	bool InitCheck(void) const;
70 
71 	void Unload(void);
72 	bool IsLoaded(void) const;
73 
74 	status_t SetDefaultInstrumentsFile();
75 	status_t SetInstrumentsFile(const char* path);
76 
77 	status_t LoadAllInstruments();
78 	status_t LoadInstrument(int16 instrument);
79 	status_t UnloadInstrument(int16 instrument);
80 	status_t RemapInstrument(int16 from, int16 to);
81 	void FlushInstrumentCache(bool startStopCache);
82 
83 	void SetVolume(double volume);
84 	double Volume(void) const;
85 
86 	status_t SetSamplingRate(int32 rate);
87 	int32 SamplingRate() const;
88 
89 	status_t SetInterpolation(interpolation_mode mode);
90 	interpolation_mode Interpolation() const;
91 
92 	status_t EnableReverb(bool enabled);
93 	bool IsReverbEnabled() const;
94 	void SetReverb(reverb_mode mode);
95 	reverb_mode Reverb() const;
96 
97 	status_t SetMaxVoices(int32 max);
98 	int16 MaxVoices(void) const;
99 
100 	status_t SetLimiterThreshold(int32 threshold);
101 	int16 LimiterThreshold(void) const;
102 
103 	void Pause(void);
104 	void Resume(void);
105 
106 	void NoteOff(uchar, uchar, uchar, uint32);
107 	void NoteOn(uchar, uchar, uchar, uint32);
108 	void KeyPressure(uchar, uchar, uchar, uint32);
109 	void ControlChange(uchar, uchar, uchar, uint32);
110 	void ProgramChange(uchar, uchar, uint32);
111  	void ChannelPressure(uchar, uchar, uint32);
112 	void PitchBend(uchar, uchar, uchar, uint32);
113 	void SystemExclusive(void*, size_t, uint32);
114 	void SystemCommon(uchar, uchar, uchar, uint32);
115 	void SystemRealTime(uchar, uint32);
116 	void TempoChange(int32, uint32);
117 	void AllNotesOff(bool, uint32);
118 
119 private:
120 
121 	friend class BSynth;
122 	friend class BMidiSynth;
123 
124 	BSoftSynth();
125 	~BSoftSynth();
126 
127 	void Init();
128 	void Done();
129 
130 	bool initCheck;
131 	char* instrumentsFile;
132 	int32 sampleRate;
133 	interpolation_mode interpMode;
134 	int16 maxVoices;
135 	int16 limiterThreshold;
136 	reverb_mode reverbMode;
137 	bool reverbEnabled;
138 	double volumeScale;
139 
140 	/*
141 		Note: Maybe this isn't the most efficient way to do things.
142 		Now a producer connects to BMidiSynth, which is a consumer.
143 		That consumer directly calls our NoteOff() etc, methods.
144 		We create a new producer and connect it to TiMidity's consumer.
145 		It would save some indirection if BMidiSynth's consumer would
146 		be a proxy for TiMidity's. (I don't think that is possible,
147 		because BMidiSynth is a BMidi object which always creates a
148 		new consumer regardless. In any case, notes have to travel
149 		a long way before they reach TiMidity.
150 	 */
151 
152 	BMidiConsumer* consumer;
153 	BMidiLocalProducer* producer;
154 };
155 
156 } // namespace BPrivate
157 
158 #endif // _SYNTH_CONSUMER_H
159