xref: /haiku/src/kits/midi/SoftSynth.h (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
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