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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 53 * *
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