/[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 123 - (hide annotations) (download)
Mon Jun 14 19:33:16 2004 UTC (20 years ago) by schoenebeck
File size: 7297 byte(s)
* src/common: added template class 'optional<>' which can be used e.g. as
  return type whenever a value might be returned, but don't has to; this
  template class pretty much acts like a pointer of the given type, but is
  much more safer than a simple pointer
* src/audiodriver: added static class AudioDeviceFactory to create audio
  devices at runtime by using a string and to obtain driver informations
  of drivers at runtime, driver classes should simply use the macro
  REGISTER_AUDIO_OUTPUT_DRIVER(DriverName,DriverClass) in their cpp file
  to register the driver to LinuxSampler (no changes needed anymore in the
  LS code to add a new audio output driver)
* src/drivers: added classes to dynamically manage driver parameters; there
  are two different kinds of parameters: parameters which are need to
  create a new device (DeviceCreationParameterX) used to e.g. create an
  audio output device or a MIDI input device and parameters which are only
  available at runtime, means when a device is already created
  (DeviceRuntimeParameterX) which will be e.g. used as audio channel
  parameters and MIDI port parameters
* src/linuxsampler.cpp: all registered audio output drivers will be shown
  on the console on startup
* src/network: implemented configuration of audio output devices via LSCP

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

  ViewVC Help
Powered by ViewVC