/[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 221 - (show annotations) (download)
Fri Aug 20 17:25:19 2004 UTC (19 years, 7 months ago) by schoenebeck
File size: 7307 byte(s)
* src/drivers/midi/MidiInputDeviceAlsa.cpp: implemented port parameter
 "NAME" which now updates the registered ALSA seq port name as well, fixed
  port parameter "ALSA_SEQ_BINDINGS" to allow more than one binding
* src/network/lscp.y: fixed symbol STRINGVAL (that is strings encapsulated
  into apostrophes) which didn't allow space characters
* changed all driver names and driver paramaters to upper case
* fixed typo in LSCP documentation
  (section 5.3.12, was: "SET MIDI_INPUT_PORT PARAMETER",
   should be: "SET MIDI_INPUT_PORT_PARAMETER")

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, ParameterSampleRate);
35 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterChannels);
36
37 /**
38 * Open and initialize connection to the JACK system.
39 *
40 * @param Parameters - optional parameters
41 * @throws AudioOutputException on error
42 * @see AcquireChannels()
43 */
44 AudioOutputDeviceJack::AudioOutputDeviceJack(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(std::map<String,DeviceCreationParameter*>()) {
45 if ((hJackClient = jack_client_new("LinuxSampler")) == 0)
46 throw AudioOutputException("Seems Jack server not running.");
47
48 jack_set_process_callback(hJackClient, __libjack_process_callback, this);
49 jack_on_shutdown(hJackClient, __libjack_shutdown_callback, this);
50 if (jack_activate(hJackClient))
51 throw AudioOutputException("Jack: Cannot activate Jack client.");
52
53 uiMaxSamplesPerCycle = jack_get_buffer_size(hJackClient);
54
55 #if 0
56 // create amount of audio channels and jack output ports we need for autoconnect
57 for (uint p = 0; p < AutoConnectPorts; p++) {
58 // create jack output port
59 std::stringstream portid; portid << "LinuxSampler:" << p;
60 jack_port_t* newport;
61 if (newport = jack_port_register(hJackClient, portid.str().c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) {
62 hJackPorts.push_back(newport);
63 }
64 else throw AudioOutputException("Jack: Cannot register Jack output port.");
65
66 // create LS audio channel
67 std::stringstream chanid; chanid << "Jack:" << p;
68 Channels.push_back(new AudioChannel((float*) jack_port_get_buffer(newport, uiMaxSamplesPerCycle), uiMaxSamplesPerCycle, chanid.str()));
69
70 // autoconnect port
71 if (jack_connect(hJackClient, portid.str().c_str(), AutoConnectPortIDs[p].c_str())) {
72 std::stringstream err; err << "Jack: Cannot auto connect port " << p;
73 throw AudioOutputException(err.str());
74 }
75 }
76 #endif
77 }
78
79 AudioOutputDeviceJack::~AudioOutputDeviceJack() {
80 // destroy all audio channels
81 for (int c = 0; c < Channels.size(); c++) delete Channels[c];
82 // destroy jack client
83 jack_client_close(hJackClient);
84 }
85
86 /**
87 * This method should not be called directly! It will be called by
88 * libjack to demand transmission of further sample points.
89 */
90 int AudioOutputDeviceJack::Process(uint Samples) {
91 if (csIsPlaying.Pop()) {
92 // let all connected engines render 'Samples' sample points
93 return RenderAudio(Samples);
94 }
95 else {
96 // playback stop by zeroing output buffer(s) and not calling connected sampler engines to render audio
97 return RenderSilence(Samples);
98 }
99 }
100
101 void AudioOutputDeviceJack::Play() {
102 csIsPlaying.PushAndUnlock(true);
103 }
104
105 bool AudioOutputDeviceJack::IsPlaying() {
106 csIsPlaying.GetUnsafe();
107 }
108
109 void AudioOutputDeviceJack::Stop() {
110 csIsPlaying.PushAndUnlock(false);
111 }
112
113 void AudioOutputDeviceJack::AcquireChannels(uint uiChannels) {
114 if (uiChannels > this->Channels.size()) {
115 for (int c = this->Channels.size(); c < uiChannels; c++) {
116 // create new jack output port
117 std::stringstream portid; portid << "LinuxSampler:" << c;
118 jack_port_t* newport;
119 if (newport = jack_port_register(hJackClient, portid.str().c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) {
120 hJackPorts.push_back(newport);
121 }
122 else throw AudioOutputException("Jack: Cannot register Jack output port.");
123
124 // create LS audio channel
125 std::stringstream chanid; chanid << "Jack:" << c;
126 Channels.push_back(new AudioChannel((float*) jack_port_get_buffer(newport, uiMaxSamplesPerCycle), uiMaxSamplesPerCycle, chanid.str()));
127 }
128 }
129 }
130
131 uint AudioOutputDeviceJack::MaxSamplesPerCycle() {
132 return jack_get_buffer_size(hJackClient);
133 }
134
135 uint AudioOutputDeviceJack::SampleRate() {
136 return jack_get_sample_rate(hJackClient);
137 }
138
139 String AudioOutputDeviceJack::Name() {
140 return "JACK";
141 }
142
143 String AudioOutputDeviceJack::Driver() {
144 return Name();
145 }
146
147 String AudioOutputDeviceJack::Description() {
148 return "JACK Audio Connection Kit";
149 }
150
151 String AudioOutputDeviceJack::Version() {
152 String s = "$Revision: 1.10 $";
153 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
154 }
155
156 // libjack callback functions
157
158 int __libjack_process_callback(jack_nframes_t nframes, void* arg) {
159 AudioOutputDeviceJack* pAudioOutputDeviceJack = (AudioOutputDeviceJack*) arg;
160 return pAudioOutputDeviceJack->Process(nframes);
161 }
162
163 void __libjack_shutdown_callback(void* arg) {
164 AudioOutputDeviceJack* pAudioOutputDeviceJack = (AudioOutputDeviceJack*) arg;
165 pAudioOutputDeviceJack->Stop();
166 fprintf(stderr, "Jack: Jack server shutdown, exiting.\n");
167 }
168
169 } // namespace LinuxSampler
170
171 #endif // HAVE_JACK

  ViewVC Help
Powered by ViewVC