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

Contents of /linuxsampler/trunk/src/audiodriver/AudioOutputDeviceJack.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 56 - (show annotations) (download)
Tue Apr 27 09:21:58 2004 UTC (19 years, 11 months ago) by schoenebeck
File size: 6952 byte(s)
updated copyright header for 2004

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
25 #if HAVE_JACK
26
27 namespace LinuxSampler {
28
29 /**
30 * Open and initialize connection to the JACK system. The two arguments
31 * are optional; they allow auto connection to already existing Jack
32 * playback ports. If there are no playback ports to which we should
33 * autoconnect to, then no output ports will be created and the
34 * AcquireChannels() method has to be called to order a minimum amount
35 * of output channels which will then be created.
36 *
37 * @param AutoConnectPortIDs - (optional) array of Jack IDs of ports to
38 * which we should autoconnect to
39 * @param AutoConnectPorts - (optional) size of the AutoConnectPortIDs
40 * array
41 * @throws AudioOutputException on error
42 * @see AcquireChannels()
43 */
44 AudioOutputDeviceJack::AudioOutputDeviceJack(String* AutoConnectPortIDs, uint AutoConnectPorts) : AudioOutputDevice() {
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 // create amount of audio channels and jack output ports we need for autoconnect
56 for (uint p = 0; p < AutoConnectPorts; p++) {
57 // create jack output port
58 std::stringstream portid; portid << "LinuxSampler:" << p;
59 jack_port_t* newport;
60 if (newport = jack_port_register(hJackClient, portid.str().c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) {
61 hJackPorts.push_back(newport);
62 }
63 else throw AudioOutputException("Jack: Cannot register Jack output port.");
64
65 // create LS audio channel
66 std::stringstream chanid; chanid << "Jack:" << p;
67 Channels.push_back(new AudioChannel((float*) jack_port_get_buffer(newport, uiMaxSamplesPerCycle), uiMaxSamplesPerCycle, chanid.str()));
68
69 // autoconnect port
70 if (jack_connect(hJackClient, portid.str().c_str(), AutoConnectPortIDs[p].c_str())) {
71 std::stringstream err; err << "Jack: Cannot auto connect port " << p;
72 throw AudioOutputException(err.str());
73 }
74 }
75 }
76
77 AudioOutputDeviceJack::~AudioOutputDeviceJack() {
78 // destroy all audio channels
79 for (int c = 0; c < Channels.size(); c++) delete Channels[c];
80 // destroy jack client
81 jack_client_close(hJackClient);
82 }
83
84 /**
85 * This method should not be called directly! It will be called by
86 * libjack to demand transmission of further sample points.
87 */
88 int AudioOutputDeviceJack::Process(uint Samples) {
89 if (csIsPlaying.Pop()) {
90 // let all connected engines render 'Samples' sample points
91 return RenderAudio(Samples);
92 }
93 else {
94 // playback stop by zeroing output buffer(s) and not calling connected sampler engines to render audio
95 return RenderSilence(Samples);
96 }
97 }
98
99 void AudioOutputDeviceJack::Play() {
100 csIsPlaying.PushAndUnlock(true);
101 }
102
103 bool AudioOutputDeviceJack::IsPlaying() {
104 csIsPlaying.GetUnsafe();
105 }
106
107 void AudioOutputDeviceJack::Stop() {
108 csIsPlaying.PushAndUnlock(false);
109 }
110
111 void AudioOutputDeviceJack::AcquireChannels(uint uiChannels) {
112 if (uiChannels > this->Channels.size()) {
113 for (int c = uiChannels; c < uiChannels; c++) {
114 // create new jack output port
115 std::stringstream portid; portid << "LinuxSampler:" << c;
116 jack_port_t* newport;
117 if (newport = jack_port_register(hJackClient, portid.str().c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) {
118 hJackPorts.push_back(newport);
119 }
120 else throw AudioOutputException("Jack: Cannot register Jack output port.");
121
122 // create LS audio channel
123 std::stringstream chanid; chanid << "Jack:" << c;
124 Channels.push_back(new AudioChannel((float*) jack_port_get_buffer(newport, uiMaxSamplesPerCycle), uiMaxSamplesPerCycle, chanid.str()));
125 }
126 }
127 }
128
129 uint AudioOutputDeviceJack::MaxSamplesPerCycle() {
130 return jack_get_buffer_size(hJackClient);
131 }
132
133 uint AudioOutputDeviceJack::SampleRate() {
134 return jack_get_sample_rate(hJackClient);
135 }
136
137
138
139 // libjack callback functions
140
141 int __libjack_process_callback(jack_nframes_t nframes, void* arg) {
142 AudioOutputDeviceJack* pAudioOutputDeviceJack = (AudioOutputDeviceJack*) arg;
143 return pAudioOutputDeviceJack->Process(nframes);
144 }
145
146 void __libjack_shutdown_callback(void* arg) {
147 AudioOutputDeviceJack* pAudioOutputDeviceJack = (AudioOutputDeviceJack*) arg;
148 pAudioOutputDeviceJack->Stop();
149 fprintf(stderr, "Jack: Jack server shutdown, exiting.\n");
150 }
151
152 } // namespace LinuxSampler
153
154 #endif // HAVE_JACK

  ViewVC Help
Powered by ViewVC