00001 /******************************************************************************* 00002 * JackClient.cpp (JackFX) 00003 ******************************************************************************/ 00004 00005 #include "JackClient.h" 00006 #include "SoundFrame.h" 00007 00008 #include "ISoundElement.h" 00009 #include "JackPort.h" 00010 00011 JackClient* JackClient::m_singleton = NULL; 00012 00013 JackClient::JackClient() 00014 { 00015 assert(!m_singleton); 00016 m_singleton = this; 00017 00018 jack_status_t status; 00019 00020 m_client = jack_client_open("JackFX", JackNullOption, &status); 00021 if (m_client == NULL) { 00022 if (status & JackServerFailed) { 00023 throw jack_init_error("JackFX was unable to connect to the Jack server."); 00024 } 00025 else { 00026 throw jack_init_error("Jack client initialization failed."); 00027 } 00028 } 00029 00030 if (status & JackServerStarted) { 00031 cout << "Jack server started." << endl; 00032 } 00033 00034 if (status & JackNameNotUnique) { 00035 cout << "Client with name `JackFX' already existed. Client named `" << 00036 jack_get_client_name(m_client) << "'" << endl; 00037 } 00038 00039 jack_set_process_callback(m_client, JackClient::JackProcess, this); 00040 jack_on_shutdown(m_client, JackClient::JackShutdown, this); 00041 00042 if (jack_activate(m_client)) { 00043 jack_client_close(m_client); 00044 throw jack_init_error("Unable to activate client."); 00045 } 00046 00047 cout << "Jack client initialized. Sample rate is " << jack_get_sample_rate(m_client) << endl; 00048 } 00049 00050 JackClient::~JackClient() 00051 { 00052 jack_client_close(m_client); 00053 m_singleton = NULL; 00054 } 00055 00056 jack_client_t* JackClient::GetClient() const 00057 { 00058 if (m_client) { 00059 return m_client; 00060 } 00061 throw jack_client_error("Jack client does not exist."); 00062 } 00063 00064 JackClient* JackClient::GetSingleton() 00065 { 00066 if (m_singleton) { 00067 return m_singleton; 00068 } 00069 throw jack_client_error("Jack client does not exist."); 00070 } 00071 00072 pthread_t JackClient::GetThread() const 00073 { 00074 return jack_client_thread_id(m_client); 00075 } 00076 00077 void JackClient::Process(jack_nframes_t nframes) 00078 { 00079 //Generate a tick id 00080 unsigned int tickid = rand(); 00081 00082 list<JackMidiPort*>::iterator mi; 00083 for (mi = m_midiports.begin(); mi != m_midiports.end(); ++mi) { 00084 (*mi)->Read(nframes); 00085 } 00086 00087 list<ISoundSource*>::iterator si; 00088 for (si = m_sources.begin(); si != m_sources.end(); ++si) { 00089 ISoundSource::Lock l(*si); 00090 //Unconditionally update all of our sound sources. 00091 (*si)->_Update(tickid, nframes); 00092 } 00093 00094 list<ISoundElement*>::iterator ei; 00095 bool didwork = true; 00096 while (didwork) { 00097 //cout << "Executing pass." << endl; 00098 didwork = false; 00099 for (ei = m_elements.begin(); ei != m_elements.end(); ++ei) { 00100 //cout << "Testing " << *ei << endl; 00101 if ((*ei)->_Updatable(tickid)) { 00102 //cout << "Updating " << *ei << endl; 00103 (*ei)->_Update(tickid, nframes); 00104 didwork = true; 00105 } 00106 } 00107 } 00108 } 00109 00110 void JackClient::JackShutdown(void* arg) 00111 { 00112 JackClient* j = static_cast<JackClient*>(arg); 00113 } 00114 00115 int JackClient::JackProcess(jack_nframes_t nframes, void* arg) 00116 { 00117 JackClient* j = static_cast<JackClient*>(arg); 00118 j->Process(nframes); 00119 return 0; 00120 } 00121