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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 200 by schoenebeck, Tue Jul 13 22:04:16 2004 UTC revision 289 by schoenebeck, Tue Oct 19 14:41:38 2004 UTC
# Line 23  Line 23 
23  #include "AudioOutputDeviceJack.h"  #include "AudioOutputDeviceJack.h"
24  #include "AudioOutputDeviceFactory.h"  #include "AudioOutputDeviceFactory.h"
25    
26    #include <errno.h>
27    
28  #if HAVE_JACK  #if HAVE_JACK
29    
30  namespace LinuxSampler {  namespace LinuxSampler {
31    
32      REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceJack);  // *************** ParameterName ***************
33    // *
34    
35        AudioOutputDeviceJack::AudioChannelJack::ParameterName::ParameterName(AudioChannelJack* pChannel) : AudioChannel::ParameterName(ToString(pChannel->ChannelNr)) {
36            this->pChannel = pChannel;
37        }
38    
39        void AudioOutputDeviceJack::AudioChannelJack::ParameterName::OnSetValue(String s) {
40            if (jack_port_set_name(pChannel->hJackPort, s.c_str())) throw AudioOutputException("Failed to rename JACK port");
41        }
42    
43    
44    
45    // *************** ParameterJackBindings ***************
46    // *
47    
48        AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::ParameterJackBindings(AudioChannelJack* pChannel) : DeviceRuntimeParameterStrings(std::vector<String>()) {
49            this->pChannel = pChannel;
50        }
51    
52        String AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::Description() {
53            return "Bindings to other JACK clients";
54        }
55    
56        bool AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::Fix() {
57            return false;
58        }
59    
60      /* Common parameters for now they'll have to be registered here. */      std::vector<String> AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::PossibilitiesAsString() {
61      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterActive);          const char** pPortNames = jack_get_ports(pChannel->pDevice->hJackClient, NULL, NULL, JackPortIsInput);
62      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterSampleRate);          if (!pPortNames) return std::vector<String>();
63      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterChannels);          std::vector<String> result;
64            for (int i = 0; pPortNames[i]; i++) result.push_back(pPortNames[i]);
65            //free(pPortNames); FIXME: pPortNames should be freed here
66            return result;
67        }
68    
69        void AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::OnSetValue(std::vector<String> vS) {
70            // TODO: we should remove all existing bindings before we connect new ones here
71            String src_name = "LinuxSampler:" + ((DeviceRuntimeParameterString*)pChannel->Parameters["NAME"])->ValueAsString();
72            for (int i = 0; i < vS.size(); i++) {
73                String dst_name = vS[i];
74                int res = jack_connect(pChannel->pDevice->hJackClient, src_name.c_str(), dst_name.c_str());
75                if (res == EEXIST) throw AudioOutputException("Jack: Connection to port '" + dst_name + "' already established");
76                else if (res)      throw AudioOutputException("Jack: Cannot connect port '" + src_name + "' to port '" + dst_name + "'");
77            }
78        }
79    
80        String AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::Name() {
81            return "JACK_BINDINGS";
82        }
83    
84    
85    
86    // *************** AudioChannelJack ***************
87    // *
88    
89        AudioOutputDeviceJack::AudioChannelJack::AudioChannelJack(uint ChannelNr, AudioOutputDeviceJack* pDevice) throw (AudioOutputException) : AudioChannel(ChannelNr, CreateJackPort(ChannelNr, pDevice), pDevice->uiMaxSamplesPerCycle) {
90            this->pDevice   = pDevice;
91            this->ChannelNr = ChannelNr;
92            Parameters["NAME"]          = new ParameterName(this);
93            Parameters["JACK_BINDINGS"] = new ParameterJackBindings(this);
94        }
95    
96        AudioOutputDeviceJack::AudioChannelJack::~AudioChannelJack() {
97            //TODO: delete JACK port
98        }
99    
100        float* AudioOutputDeviceJack::AudioChannelJack::CreateJackPort(uint ChannelNr, AudioOutputDeviceJack* pDevice) throw (AudioOutputException) {
101            String port_id = ToString(ChannelNr);
102            hJackPort = jack_port_register(pDevice->hJackClient, port_id.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
103            if (!hJackPort) throw AudioOutputException("Jack: Cannot register Jack output port.");
104            return (float*) jack_port_get_buffer(hJackPort, pDevice->uiMaxSamplesPerCycle);
105        }
106    
107    
108    
109    // *************** AudioOutputDeviceJack ***************
110    // *
111    
112      /**      /**
113       * Open and initialize connection to the JACK system.       * Open and initialize connection to the JACK system.
# Line 41  namespace LinuxSampler { Line 116  namespace LinuxSampler {
116       * @throws AudioOutputException  on error       * @throws AudioOutputException  on error
117       * @see AcquireChannels()       * @see AcquireChannels()
118       */       */
119      AudioOutputDeviceJack::AudioOutputDeviceJack(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(std::map<String,DeviceCreationParameter*>()) {      AudioOutputDeviceJack::AudioOutputDeviceJack(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters) {
120          if ((hJackClient = jack_client_new("LinuxSampler")) == 0)          if ((hJackClient = jack_client_new("LinuxSampler")) == 0)
121              throw AudioOutputException("Seems Jack server not running.");              throw AudioOutputException("Seems Jack server not running.");
122    
# Line 52  namespace LinuxSampler { Line 127  namespace LinuxSampler {
127    
128          uiMaxSamplesPerCycle = jack_get_buffer_size(hJackClient);          uiMaxSamplesPerCycle = jack_get_buffer_size(hJackClient);
129    
130  #if 0          // create audio channels
131          // create amount of audio channels and jack output ports we need for autoconnect          AcquireChannels(((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt());
132          for (uint p = 0; p < AutoConnectPorts; p++) {  
133              // create jack output port          // finally activate device if desired
134              std::stringstream portid; portid << "LinuxSampler:" << p;          if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) Play();
             jack_port_t* newport;  
             if (newport = jack_port_register(hJackClient, portid.str().c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) {  
                 hJackPorts.push_back(newport);  
             }  
             else throw AudioOutputException("Jack: Cannot register Jack output port.");  
   
             // create LS audio channel  
             std::stringstream chanid; chanid << "Jack:" << p;  
             Channels.push_back(new AudioChannel((float*) jack_port_get_buffer(newport, uiMaxSamplesPerCycle), uiMaxSamplesPerCycle, chanid.str()));  
   
             // autoconnect port  
             if (jack_connect(hJackClient, portid.str().c_str(), AutoConnectPortIDs[p].c_str())) {  
                 std::stringstream err; err << "Jack: Cannot auto connect port " << p;  
                 throw AudioOutputException(err.str());  
             }  
         }  
 #endif  
135      }      }
136    
137      AudioOutputDeviceJack::~AudioOutputDeviceJack() {      AudioOutputDeviceJack::~AudioOutputDeviceJack() {
         // destroy all audio channels  
         for (int c = 0; c < Channels.size(); c++) delete Channels[c];  
138          // destroy jack client          // destroy jack client
139          jack_client_close(hJackClient);          jack_client_close(hJackClient);
140      }      }
# Line 110  namespace LinuxSampler { Line 166  namespace LinuxSampler {
166          csIsPlaying.PushAndUnlock(false);          csIsPlaying.PushAndUnlock(false);
167      }      }
168    
169      void AudioOutputDeviceJack::AcquireChannels(uint uiChannels) {      AudioChannel* AudioOutputDeviceJack::CreateChannel(uint ChannelNr) {
170          if (uiChannels > this->Channels.size()) {          return new AudioChannelJack(ChannelNr, this);
             for (int c = this->Channels.size(); c < uiChannels; c++) {  
                 // create new jack output port  
                 std::stringstream portid; portid << "LinuxSampler:" << c;  
                 jack_port_t* newport;  
                 if (newport = jack_port_register(hJackClient, portid.str().c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) {  
                     hJackPorts.push_back(newport);  
                 }  
                 else throw AudioOutputException("Jack: Cannot register Jack output port.");  
   
                 // create LS audio channel  
                 std::stringstream chanid; chanid << "Jack:" << c;  
                 Channels.push_back(new AudioChannel((float*) jack_port_get_buffer(newport, uiMaxSamplesPerCycle), uiMaxSamplesPerCycle, chanid.str()));  
             }  
         }  
171      }      }
172    
173      uint AudioOutputDeviceJack::MaxSamplesPerCycle() {      uint AudioOutputDeviceJack::MaxSamplesPerCycle() {
# Line 137  namespace LinuxSampler { Line 179  namespace LinuxSampler {
179      }      }
180    
181      String AudioOutputDeviceJack::Name() {      String AudioOutputDeviceJack::Name() {
182          return "Jack";          return "JACK";
183      }      }
184    
185      String AudioOutputDeviceJack::Driver() {      String AudioOutputDeviceJack::Driver() {
# Line 149  namespace LinuxSampler { Line 191  namespace LinuxSampler {
191      }      }
192    
193      String AudioOutputDeviceJack::Version() {      String AudioOutputDeviceJack::Version() {
194         String s = "$Revision: 1.9 $";         String s = "$Revision: 1.14 $";
195         return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword         return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
196      }      }
197    

Legend:
Removed from v.200  
changed lines
  Added in v.289

  ViewVC Help
Powered by ViewVC