00001
00029 #include <sys/time.h>
00030 #include <netdb.h>
00031 #include <pthread.h>
00032 #include <sys/socket.h>
00033 #include <sys/types.h>
00034 #include <sys/wait.h>
00035 #include <sys/msg.h>
00036 #include <sys/ipc.h>
00037 #include <arpa/inet.h>
00038 #include <netinet/in.h>
00039 #include <queue.h>
00040
00041 #include "include/Netmusic.hh"
00042 #include "include/Mini.hh"
00043
00047 snd_seq_t* senderSeqHandler = NULL;
00051 int npfd;
00055 struct pollfd* pfd;
00059 int sdMini;
00063 struct sockaddr_in remoteReceiverAddrMini;
00067 queue<int>miniOnQueue;
00071 queue<int>miniOffQueue;
00075 int mini = 1;
00079 int syncPort = 29998;
00083 int midiPort = 29999;
00087 int miniPort = 30000;
00091 int startKey = 36;
00095 char* receiverIp = new char[15];
00099 int threshold = 200;
00103 pthread_t miniOnThread, miniOffThread, midiThread, syncThread;
00107 pthread_mutex_t mutexOn = PTHREAD_MUTEX_INITIALIZER;
00111 pthread_mutex_t mutexOff = PTHREAD_MUTEX_INITIALIZER;
00115 pthread_mutex_t mutexMini = PTHREAD_MUTEX_INITIALIZER;
00116
00117
00118
00123 void handler(int signal)
00124 {
00125 if ( signal == SIGINT)
00126 _exit(0);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 void *midi_function(void *ptr)
00141 {
00142
00143 std::cout << "SENDER: MIDI Thread started..." << std::endl;
00144
00145
00146 struct sockaddr_in senderAddrMidi, remoteReceiverAddrMidi;
00147 struct hostent *h;
00148 int sdMidi, rcMidi;
00149 snd_seq_event_t* ev;
00150
00151 h = gethostbyname(receiverIp);
00152
00153
00154 remoteReceiverAddrMidi.sin_family = h->h_addrtype;
00155 remoteReceiverAddrMidi.sin_port = htons(midiPort);
00156 memcpy((char *)&remoteReceiverAddrMidi.sin_addr.s_addr,
00157 h->h_addr_list[0], h->h_length);
00158 sdMidi = socket(AF_INET, SOCK_DGRAM, 0);
00159 Netmusic::check_error(sdMidi, "Error creating midi socket");
00160
00161 senderAddrMidi.sin_family = AF_INET;
00162 senderAddrMidi.sin_addr.s_addr = htonl(INADDR_ANY);
00163 senderAddrMidi.sin_port = htons(0);
00164
00165 rcMidi = bind(sdMidi, (struct sockaddr *) &senderAddrMidi, sizeof(senderAddrMidi));
00166 Netmusic::check_error(rcMidi, "Error binding to senderAddr");
00167
00168
00169 while(1)
00170 {
00171 if( poll(pfd, npfd, 100000) > 0)
00172 {
00173 do
00174 {
00175 snd_seq_event_input(senderSeqHandler, &ev);
00176
00177 Netmusic::print_read_data(ev);
00178
00179
00180 if(mini==0)
00181 {
00182 if( ev->type == SND_SEQ_EVENT_NOTEON ||
00183 ev->type == SND_SEQ_EVENT_NOTEOFF ||
00184 ev->type == SND_SEQ_EVENT_PGMCHANGE )
00185 {
00186 rcMidi = sendto(sdMidi, ev, (sizeof(snd_seq_event_t)), 0,
00187 (struct sockaddr *) &remoteReceiverAddrMidi, sizeof(remoteReceiverAddrMidi));
00188 Netmusic::check_error(rcMidi, "Error sending to remote machine");
00189 }
00190 }
00191
00192
00193 else if(mini==1)
00194 {
00195 switch (ev->type)
00196 {
00197 case SND_SEQ_EVENT_NOTEON:
00198
00199
00200 if(ev->data.note.velocity != 0)
00201 {
00202 pthread_mutex_lock(&mutexOn);
00203 miniOnQueue.push(ev->data.note.note);
00204 pthread_mutex_unlock(&mutexOn);
00205 }
00206
00207 else
00208 {
00209 pthread_mutex_lock(&mutexOff);
00210 miniOffQueue.push(ev->data.note.note);
00211 pthread_mutex_unlock(&mutexOff);
00212 }
00213
00214 break;
00215
00216 case SND_SEQ_EVENT_NOTEOFF:
00217
00218 pthread_mutex_lock(&mutexOff);
00219 miniOffQueue.push(ev->data.note.note);
00220 pthread_mutex_unlock(&mutexOff);
00221 break;
00222
00223 }
00224 }
00225
00226 snd_seq_free_event(ev);
00227
00228 } while( snd_seq_event_input_pending(senderSeqHandler, 0) > 0);
00229 }
00230 }
00231 pthread_exit(NULL);
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 void *mini_on_function(void *ptr)
00247 {
00248
00249 std::cout << "SENDER: MINI ON Thread started..." << std::endl;
00250
00251
00252 mpz_t miniOnWord;
00253 mpz_t tempWord1, tempWord2;
00254 char* binaryMiniOnWord;
00255 int* noteOnArray;
00256 int size, i=0, size_mem_mpz, localNoteOff=0, rcMini, tmp;
00257
00258
00259 mpz_init(miniOnWord);
00260 mpz_init(tempWord1);
00261 mpz_init(tempWord2);
00262 mpz_set_ui(miniOnWord,0);
00263
00264
00265 while(1)
00266 {
00267 usleep(threshold*1000);
00268
00269 pthread_mutex_lock(&mutexOn);
00270
00271 if(!miniOnQueue.empty())
00272 {
00273 size = miniOnQueue.size();
00274 noteOnArray = new int[size];
00275
00276 while(!miniOnQueue.empty())
00277 {
00278 tmp = miniOnQueue.front();
00279 noteOnArray[i] = tmp-startKey;
00280 miniOnQueue.pop();
00281 i++;
00282 }
00283 pthread_mutex_unlock(&mutexOn);
00284
00285
00286
00287 mpz_set_ui(miniOnWord,0);
00288 Mini::sort_array(noteOnArray, size);
00289 Mini::ksub_rank( size, noteOnArray, miniOnWord);
00290 mpz_set(tempWord1, miniOnWord);
00291 mpz_set(tempWord2, miniOnWord);
00292 size_mem_mpz = Mini::get_size_mem_mpz(tempWord1);
00293 binaryMiniOnWord = (char*)new char[size_mem_mpz];
00294 Mini::mpz_2_bin(tempWord2, size, localNoteOff, binaryMiniOnWord);
00295
00296
00297 std::cout << DELIMITER << std::endl;
00298 Mini::print_array(noteOnArray, size, startKey);
00299 gmp_printf("\n rank: %Zd\n", miniOnWord);
00300 Mini::print_mem( binaryMiniOnWord, size_mem_mpz);
00301 std::cout << " mpz_size: " << size_mem_mpz << std::endl;
00302 std::cout << " k: " << size << std::endl;
00303 std::cout << " noteOff: " << localNoteOff << std::endl << std::endl;
00304
00305
00306 pthread_mutex_lock(&mutexMini);
00307 std::cout << "SENDER: Sending MINI ON WORD 1st Read to receiver..." << std::endl;
00308 rcMini = sendto(sdMini, binaryMiniOnWord, (sizeof(char)), 0,
00309 (struct sockaddr *) &remoteReceiverAddrMini, sizeof(remoteReceiverAddrMini));
00310 Netmusic::check_error(rcMini, "Error sending 1st read on");
00311 binaryMiniOnWord++;
00312 std::cout << "SENDER: Sending MINI ON WORD 2nd Read to receiver..." << std::endl;
00313 rcMini = sendto(sdMini, binaryMiniOnWord, ((size_mem_mpz-1)*sizeof(char)), 0,
00314 (struct sockaddr *) &remoteReceiverAddrMini, sizeof(remoteReceiverAddrMini));
00315 Netmusic::check_error(rcMini, "Error sending 2nd read on");
00316 pthread_mutex_unlock(&mutexMini);
00317
00318 i=0;
00319 }
00320
00321 pthread_mutex_unlock(&mutexOn);
00322 }
00323 close(sdMini);
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 void *mini_off_function(void *ptr)
00339 {
00340
00341 std::cout << "SENDER: MINI OFF Thread started..." << std::endl;
00342
00343
00344 mpz_t miniOffWord;
00345 mpz_t tempWord1, tempWord2;
00346 char* binaryMiniOffWord;
00347 int* noteOffArray;
00348 int size, i=0, size_mem_mpz, localNoteOff=1, rcMini, tmp;
00349
00350
00351 mpz_init(miniOffWord);
00352 mpz_init(tempWord1);
00353 mpz_init(tempWord2);
00354 mpz_set_ui(miniOffWord,0);
00355
00356
00357 while(1)
00358 {
00359 usleep(threshold*1000);
00360
00361 pthread_mutex_lock(&mutexOff);
00362
00363 if(!miniOffQueue.empty())
00364 {
00365 size = miniOffQueue.size();
00366 noteOffArray = new int[size];
00367
00368 while(!miniOffQueue.empty())
00369 {
00370 tmp = miniOffQueue.front();
00371 noteOffArray[i] = tmp-startKey;
00372 miniOffQueue.pop();
00373 i++;
00374 }
00375 pthread_mutex_unlock(&mutexOff);
00376
00377
00378 mpz_set_ui(miniOffWord,0);
00379 Mini::sort_array(noteOffArray, size);
00380 Mini::ksub_rank( size, noteOffArray, miniOffWord);
00381 mpz_set(tempWord1, miniOffWord);
00382 mpz_set(tempWord2, miniOffWord);
00383 size_mem_mpz = Mini::get_size_mem_mpz(tempWord1);
00384 binaryMiniOffWord = (char*)new char[size_mem_mpz];
00385 Mini::mpz_2_bin(tempWord2, size, localNoteOff, binaryMiniOffWord);
00386
00387
00388 std::cout << DELIMITER << std::endl;
00389 Mini::print_array(noteOffArray, size, startKey);
00390 gmp_printf("\n rank: %Zd\n", miniOffWord);
00391 Mini::print_mem( binaryMiniOffWord, size_mem_mpz);
00392 std::cout << " mpz_size: " << size_mem_mpz << std::endl;
00393 std::cout << " k: " << size << std::endl;
00394 std::cout << " noteOff: " << localNoteOff << std::endl << std::endl;
00395
00396
00397 pthread_mutex_lock(&mutexMini);
00398 std::cout << "SENDER: Sending MINI OFF WORD 1st Read to receiver..." << std::endl;
00399 rcMini = sendto(sdMini, binaryMiniOffWord, (sizeof(char)), 0,
00400 (struct sockaddr *) &remoteReceiverAddrMini, sizeof(remoteReceiverAddrMini));
00401 Netmusic::check_error(rcMini, "Error sending 1st read off");
00402 binaryMiniOffWord++;
00403 std::cout << "SENDER: Sending MINI OFF WORD 2nd Read to receiver..." << std::endl;
00404 rcMini = sendto(sdMini, binaryMiniOffWord, ((size_mem_mpz-1)*sizeof(char)), 0,
00405 (struct sockaddr *) &remoteReceiverAddrMini, sizeof(remoteReceiverAddrMini));
00406 Netmusic::check_error(rcMini, "Error sending 2nd read off");
00407 pthread_mutex_unlock(&mutexMini);
00408
00409 i=0;
00410 }
00411
00412 pthread_mutex_unlock(&mutexOff);
00413 }
00414 close(sdMini);
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 void *sync_function(void *ptr)
00427 {
00428
00429 struct sockaddr_in senderAddrSync, remoteReceiverAddr;
00430 struct hostent *h;
00431 int sd, rc;
00432 int* arrayPointer = new int[4];
00433
00434 h = gethostbyname(receiverIp);
00435
00436
00437 remoteReceiverAddr.sin_family = h->h_addrtype;
00438 remoteReceiverAddr.sin_port = htons(syncPort);
00439 memcpy((char *)&remoteReceiverAddr.sin_addr.s_addr,
00440 h->h_addr_list[0], h->h_length);
00441
00442 sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
00443 Netmusic::check_error(sd, "Error creating sync socket");
00444
00445 senderAddrSync.sin_family = AF_INET;
00446 senderAddrSync.sin_addr.s_addr = htonl(INADDR_ANY);
00447 senderAddrSync.sin_port = htons(0);
00448
00449 rc = bind(sd, (struct sockaddr *) &senderAddrSync, sizeof(senderAddrSync));
00450 Netmusic::check_error(rc, "Error binding to senderAddr");
00451
00452
00453 arrayPointer[0] = mini;
00454 arrayPointer[1] = midiPort;
00455 arrayPointer[2] = miniPort;
00456 arrayPointer[3] = startKey;
00457
00458 rc = sendto(sd, arrayPointer, (4*sizeof(int)), 0,
00459 (struct sockaddr *) &remoteReceiverAddr, sizeof(remoteReceiverAddr));
00460 Netmusic::check_error(rc, "Error sending sync data");
00461
00462 close(sd);
00463
00464 std::cout << DELIMITER << std::endl;
00465 std::cout << "Sending sync data to receiver..." << std::endl;
00466 std::cout << "Sync complete." << std::endl;
00467
00468 pthread_exit(NULL);
00469 }
00470
00471
00481 int main(int argc, char** argv)
00482 {
00483 signal(SIGINT, handler);
00484
00485
00486 Netmusic::sender_check_args(argc, argv,
00487 &mini,
00488 &midiPort, &miniPort, &syncPort,
00489 &startKey, &threshold,
00490 receiverIp);
00491
00492
00493 int rcMini;
00494 struct sockaddr_in senderAddrMini;
00495 struct hostent *h;
00496 h = gethostbyname(receiverIp);
00497
00498 remoteReceiverAddrMini.sin_family = h->h_addrtype;
00499 remoteReceiverAddrMini.sin_port = htons(miniPort);
00500 memcpy((char *)&remoteReceiverAddrMini.sin_addr.s_addr,
00501 h->h_addr_list[0], h->h_length);
00502
00503 sdMini = socket(AF_INET, SOCK_DGRAM, 0);
00504 Netmusic::check_error(sdMini, "Error creating mini socket");
00505
00506 senderAddrMini.sin_family = AF_INET;
00507 senderAddrMini.sin_addr.s_addr = htonl(INADDR_ANY);
00508 senderAddrMini.sin_port = htons(0);
00509
00510 rcMini = bind(sdMini, (struct sockaddr *) &senderAddrMini, sizeof(senderAddrMini));
00511 Netmusic::check_error(rcMini, "Error binding mini socket");
00512
00513
00514 senderSeqHandler = Netmusic::sender_open_seq();
00515 npfd = snd_seq_poll_descriptors_count(senderSeqHandler, POLLIN);
00516 pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd));
00517 snd_seq_poll_descriptors(senderSeqHandler, pfd, npfd, POLLIN);
00518
00519
00520 Netmusic::sender_print_welcome_msg();
00521
00522 int miniOnRet, miniOffRet, midiRet, syncRet;
00523
00524
00525 syncRet = pthread_create( &syncThread, NULL, sync_function, NULL);
00526
00527 pthread_join( syncThread, NULL);
00528
00529
00530 Netmusic::sender_print_param(
00531 mini,
00532 midiPort, miniPort, syncPort,
00533 startKey, threshold,
00534 receiverIp);
00535
00536
00537 midiRet = pthread_create( &midiThread, NULL, midi_function, NULL);
00538
00539 if(mini==1)
00540 {
00541 miniOnRet = pthread_create( &miniOnThread, NULL, mini_on_function, NULL);
00542 miniOffRet = pthread_create( &miniOffThread, NULL, mini_off_function, NULL);
00543 }
00544
00545
00546 pthread_join( midiThread, NULL);
00547
00548 if(mini==1)
00549 {
00550 pthread_join( miniOnThread, NULL);
00551 pthread_join( miniOffThread, NULL);
00552 }
00553
00554 return 0;
00555 }