/[svn]/linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceJack.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceJack.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 226 - (show annotations) (download)
Wed Aug 25 22:00:33 2004 UTC (19 years, 7 months ago) by schoenebeck
File size: 8653 byte(s)
* ALSA MIDI driver: create one MIDI port by default, implemented parameter
  info for parameter 'ALSA_SEQ_BINDINGS'
* ALSA audio driver: implemented parameter info for driver parameters
  'FRAGMENTS' and 'FRAGMENTSIZE'
* JACK audio driver: fixed creation of channels on device creation, channel
  parameter 'NAME' now actually updates the respective JACK port name,
  implemented channel parameter 'JACK_BINDINGS' (as well as its parameter
  info)
* src/network/lscpserver.cpp: fixed commands
  "GET MIDI_INPUT_DRIVER_PARAMETER INFO" and
  "GET AUDIO_OUTPUT_DRIVER_PARAMETER  INFO", fixed backward compatibility
  for "SET AUDIO_OUTPUT_TYPE" and "SET MIDI_INPUT_TYPE" commands
* src/networ/lscp.y: added comma character (',') to symbol 'char'
* src/drivers/DeviceParameter.cpp: fixed methods RangeMin(), RangeMax() in
  class DeviceCreationParameterInt which returned wrong values

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include "AudioOutputDeviceJack.h"
24 #include "AudioOutputDeviceFactory.h"
25
26 #if HAVE_JACK
27
28 namespace LinuxSampler {
29
30 REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceJack);
31
32 /* Common parameters for now they'll have to be registered here. */
33 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterActive);
34 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterChannels);
35
36
37
38 // *************** ParameterName ***************
39 // *
40
41 AudioOutputDeviceJack::AudioChannelJack::ParameterName::ParameterName(AudioChannelJack* pChannel) : AudioChannel::ParameterName(ToString(pChannel->ChannelNr)) {
42 this->pChannel = pChannel;
43 }
44
45 void AudioOutputDeviceJack::AudioChannelJack::ParameterName::OnSetValue(String s) {
46 String name = "LinuxSampler:" + s;
47 if (jack_port_set_name(pChannel->hJackPort, name.c_str())) throw AudioOutputException("Failed to rename JACK port");
48 }
49
50
51
52 // *************** ParameterJackBindings ***************
53 // *
54
55 AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::ParameterJackBindings(AudioChannelJack* pChannel) : DeviceRuntimeParameterStrings(std::vector<String>()) {
56 this->pChannel = pChannel;
57 }
58
59 String AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::Description() {
60 return "Bindings to other JACK clients";
61 }
62
63 bool AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::Fix() {
64 return false;
65 }
66
67 std::vector<String> AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::PossibilitiesAsString() {
68 const char** pPortNames = jack_get_ports(pChannel->pDevice->hJackClient, NULL, NULL, 0);
69 if (!pPortNames) return std::vector<String>();
70 std::vector<String> result;
71 for (int i = 0; pPortNames[i]; i++) result.push_back(pPortNames[i]);
72 //free(pPortNames); FIXME: pPortNames should be freed here
73 return result;
74 }
75
76 void AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::OnSetValue(std::vector<String> vS) {
77 String src_name = "LinuxSampler:" + pChannel->Parameters["NAME"]->Value();
78 for (int i = 0; i < vS.size(); i++) {
79 String dst_name = vS[i];
80 if (jack_connect(pChannel->pDevice->hJackClient, src_name.c_str(), dst_name.c_str())) {
81 throw AudioOutputException("Jack: Cannot connect to port '" + dst_name + "'");
82 }
83 }
84 }
85
86 String AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::Name() {
87 return "JACK_BINDINGS";
88 }
89
90
91
92 // *************** AudioChannelJack ***************
93 // *
94
95 AudioOutputDeviceJack::AudioChannelJack::AudioChannelJack(uint ChannelNr, AudioOutputDeviceJack* pDevice) throw (AudioOutputException) : AudioChannel(ChannelNr, CreateJackPort(ChannelNr, pDevice), pDevice->uiMaxSamplesPerCycle) {
96 this->pDevice = pDevice;
97 this->ChannelNr = ChannelNr;
98 Parameters["NAME"] = new ParameterName(this);
99 Parameters["JACK_BINDINGS"] = new ParameterJackBindings(this);
100 }
101
102 AudioOutputDeviceJack::AudioChannelJack::~AudioChannelJack() {
103 //TODO: delete JACK port
104 }
105
106 float* AudioOutputDeviceJack::AudioChannelJack::CreateJackPort(uint ChannelNr, AudioOutputDeviceJack* pDevice) throw (AudioOutputException) {
107 String port_id = "LinuxSampler:" + ToString(ChannelNr);
108 hJackPort = jack_port_register(pDevice->hJackClient, port_id.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
109 if (!hJackPort) throw AudioOutputException("Jack: Cannot register Jack output port.");
110 return (float*) jack_port_get_buffer(hJackPort, pDevice->uiMaxSamplesPerCycle);
111 }
112
113
114
115 // *************** AudioOutputDeviceJack ***************
116 // *
117
118 /**
119 * Open and initialize connection to the JACK system.
120 *
121 * @param Parameters - optional parameters
122 * @throws AudioOutputException on error
123 * @see AcquireChannels()
124 */
125 AudioOutputDeviceJack::AudioOutputDeviceJack(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters) {
126 if ((hJackClient = jack_client_new("LinuxSampler")) == 0)
127 throw AudioOutputException("Seems Jack server not running.");
128
129 jack_set_process_callback(hJackClient, __libjack_process_callback, this);
130 jack_on_shutdown(hJackClient, __libjack_shutdown_callback, this);
131 if (jack_activate(hJackClient))
132 throw AudioOutputException("Jack: Cannot activate Jack client.");
133
134 uiMaxSamplesPerCycle = jack_get_buffer_size(hJackClient);
135
136 // create audio channels
137 AcquireChannels(((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt());
138 }
139
140 AudioOutputDeviceJack::~AudioOutputDeviceJack() {
141 // destroy jack client
142 jack_client_close(hJackClient);
143 }
144
145 /**
146 * This method should not be called directly! It will be called by
147 * libjack to demand transmission of further sample points.
148 */
149 int AudioOutputDeviceJack::Process(uint Samples) {
150 if (csIsPlaying.Pop()) {
151 // let all connected engines render 'Samples' sample points
152 return RenderAudio(Samples);
153 }
154 else {
155 // playback stop by zeroing output buffer(s) and not calling connected sampler engines to render audio
156 return RenderSilence(Samples);
157 }
158 }
159
160 void AudioOutputDeviceJack::Play() {
161 csIsPlaying.PushAndUnlock(true);
162 }
163
164 bool AudioOutputDeviceJack::IsPlaying() {
165 csIsPlaying.GetUnsafe();
166 }
167
168 void AudioOutputDeviceJack::Stop() {
169 csIsPlaying.PushAndUnlock(false);
170 }
171
172 AudioChannel* AudioOutputDeviceJack::CreateChannel(uint ChannelNr) {
173 return new AudioChannelJack(ChannelNr, this);
174 }
175
176 uint AudioOutputDeviceJack::MaxSamplesPerCycle() {
177 return jack_get_buffer_size(hJackClient);
178 }
179
180 uint AudioOutputDeviceJack::SampleRate() {
181 return jack_get_sample_rate(hJackClient);
182 }
183
184 String AudioOutputDeviceJack::Name() {
185 return "JACK";
186 }
187
188 String AudioOutputDeviceJack::Driver() {
189 return Name();
190 }
191
192 String AudioOutputDeviceJack::Description() {
193 return "JACK Audio Connection Kit";
194 }
195
196 String AudioOutputDeviceJack::Version() {
197 String s = "$Revision: 1.11 $";
198 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
199 }
200
201 // libjack callback functions
202
203 int __libjack_process_callback(jack_nframes_t nframes, void* arg) {
204 AudioOutputDeviceJack* pAudioOutputDeviceJack = (AudioOutputDeviceJack*) arg;
205 return pAudioOutputDeviceJack->Process(nframes);
206 }
207
208 void __libjack_shutdown_callback(void* arg) {
209 AudioOutputDeviceJack* pAudioOutputDeviceJack = (AudioOutputDeviceJack*) arg;
210 pAudioOutputDeviceJack->Stop();
211 fprintf(stderr, "Jack: Jack server shutdown, exiting.\n");
212 }
213
214 } // namespace LinuxSampler
215
216 #endif // HAVE_JACK

  ViewVC Help
Powered by ViewVC