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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 200 - (hide annotations) (download)
Tue Jul 13 22:04:16 2004 UTC (19 years, 9 months ago) by schoenebeck
File size: 7299 byte(s)
moved directory '/src/audiodriver' -> '/src/drivers/audio'

1 schoenebeck 200 /***************************************************************************
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.9 $";
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