JackPort.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * JackPort.cpp (JackFX) 
00003  ******************************************************************************/
00004 
00005 #include "JackPort.h"
00006 #include "JackClient.h"
00007 
00008 JackPort::JackPort(const string& name, bool writer, const char* type) : m_writer(writer)
00009 {
00010     m_port = jack_port_register(JackClient::GetSingleton()->GetClient(), name.c_str(), 
00011             type, (m_writer ? JackPortIsOutput : JackPortIsInput) | JackPortIsTerminal, 0);
00012 }
00013 
00014 JackPort::~JackPort()
00015 {
00016     try {
00017         jack_port_unregister(JackClient::GetSingleton()->GetClient(), m_port);
00018     }
00019     catch(...) {} //Ignore.
00020 }
00021 
00022 bool JackPort::ConnectTo(const string& destport)
00023 {
00024     const char* in = m_writer ? destport.c_str() : jack_port_name(GetPort());
00025     const char* out = m_writer ? jack_port_name(GetPort()) : destport.c_str();
00026 
00027     int result = jack_connect(JackClient::GetSingleton()->GetClient(), out, in);
00028     
00029     if (result == 0) {
00030         return true;
00031     }
00032     else if (result == EEXIST) {
00033         return false;
00034     }
00035     else {
00036         throw runtime_error("Could not connect to port `" + destport + "'.");
00037     }
00038 }
00039 
00040 void JackPort::DisconnectFrom(const string& destport)
00041 {
00042     int result = jack_disconnect(JackClient::GetSingleton()->GetClient(),
00043         jack_port_name(GetPort()), destport.c_str());
00044     
00045     if (result != 0) {
00046         throw runtime_error("Could not disconnect from port `" + destport + "'.");
00047     }
00048 }
00049 
00050 JackMidiPort::JackMidiPort(const string& name, bool writer) :
00051         JackPort(name, writer, JACK_DEFAULT_MIDI_TYPE)
00052 {
00053     pthread_mutex_init(&m_mtx, NULL);
00054     JackClient::GetSingleton()->m_midiports.push_back(this);
00055 }
00056 
00057 JackMidiPort::~JackMidiPort()
00058 {
00059     pthread_mutex_destroy(&m_mtx);
00060     if (JackClient::GetSingleton()) {
00061         JackClient::GetSingleton()->m_midiports.remove(this);
00062     }
00063 }
00064 
00065 queue<jack_midi_event_t>& JackMidiPort::GetEventQueue()
00066 {
00067     return m_eventqueue;
00068 }
00069 
00070 python::object JackMidiPort::GetPyEventQueue()
00071 {
00072     pthread_mutex_lock(&m_mtx);
00073     python::list ret;
00074     while (m_eventqueue.size()) {
00075         jack_midi_event_t& evt = m_eventqueue.front();
00076 
00077         //I don't know a better way of doing this.
00078         //using namespace boost::python;
00079         switch(evt.size) {
00080             case 1:
00081                 ret.append(python::make_tuple(evt.buffer[0]));
00082                 break;
00083             case 2:
00084                 ret.append(python::make_tuple(evt.buffer[0], evt.buffer[1]));
00085                 break;
00086             case 3:
00087                 ret.append(python::make_tuple(evt.buffer[0], evt.buffer[1], evt.buffer[2]));
00088                 break;
00089             case 4:
00090                 ret.append(python::make_tuple(evt.buffer[0], evt.buffer[1], evt.buffer[2], evt.buffer[3]));
00091                 break;
00092             default:
00093                 ret.append(python::make_tuple(evt.buffer[0], evt.buffer[1], evt.buffer[2], evt.buffer[3], evt.buffer[4]));
00094                 break;
00095         }
00096 
00097         m_eventqueue.pop();
00098     }
00099     pthread_mutex_unlock(&m_mtx);
00100 
00101     return ret;
00102 }
00103 
00104 void JackMidiPort::Read(jack_nframes_t nframes)
00105 {
00106     pthread_mutex_lock(&m_mtx);
00107     void* port_buf = jack_port_get_buffer(GetPort(), nframes);
00108 
00109     jack_nframes_t eventcount = jack_midi_get_event_count(port_buf);
00110     for (int i = 0; i < eventcount; ++i) {
00111         jack_midi_event_t in_evt;
00112         jack_midi_event_get(&in_evt, port_buf, i);
00113         m_eventqueue.push(in_evt);
00114         /*cout << "Event " << i << " time is " << in_evt.time << ". 1st byte is " << (int)*(in_evt.buffer) << endl;
00115         for (unsigned int x = 0; x < in_evt.size; ++x) {
00116             cout << "\tByte " << x << " is " << (int)(in_evt.buffer[x]) << endl;
00117         }*/
00118     }
00119     pthread_mutex_unlock(&m_mtx);
00120 }
00121 
00122 void JackAudioPort::GetFrame(SoundFrame& frame, jack_nframes_t nframes)
00123 {
00124     frame.Set((jack_default_audio_sample_t*)jack_port_get_buffer(GetPort(), nframes), nframes);
00125 }
00126 
00127 void JackAudioPort::PutFrame(const SoundFrame& frame)
00128 {
00129     void* out = jack_port_get_buffer(GetPort(), frame.SampleCount());
00130     memcpy(out, frame.GetSamples(), sizeof(jack_default_audio_sample_t) * frame.SampleCount());
00131 }
00132 
00133 JackInput::JackInput(const string& name) : JackAudioPort(name, false)
00134 {
00135 }
00136 
00137 JackInput::~JackInput()
00138 {
00139 }
00140 
00141 void JackInput::Process(jack_nframes_t samples)
00142 {
00143     //Fill our pipe with our jack port input.
00144     GetFrame(GetPipe(), samples);
00145 }
00146 
00147 JackOutput::JackOutput(const string& name) : JackAudioPort(name, true)
00148 {
00149 }
00150 
00151 JackOutput::~JackOutput()
00152 {
00153 }
00154 
00155 void JackOutput::Process(jack_nframes_t count)
00156 {
00157     GetPipe().Zero();
00158     ISoundElement::Process(count);
00159     //cout << GetPipe() << endl;
00160     PutFrame(GetPipe());
00161 }
00162 

Get JackFX at SourceForge.net. Fast, secure and Free Open Source software downloads
Generated for JackFX by  doxygen