00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <iostream>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <sys/types.h>
00031 #include <sys/wait.h>
00032 #include <signal.h>
00033 #include <errno.h>
00034
00035
00036 #include <audioproc.h>
00037
00038 #include <jutils.h>
00039 #include <inchannels.h>
00040 #include <config.h>
00041 #include <generic.h>
00042
00043 #ifdef HAVE_VORBIS
00044 #include <dec_ogg.h>
00045 #endif
00046 #ifdef HAVE_SNDFILE
00047 #include <dec_snd.h>
00048 #endif
00049 #ifdef HAVE_JACK
00050 #include <dec_jack.h>
00051 #endif
00052 #include <dec_mp3.h>
00053
00054 #include "httpstream.h"
00055
00056
00057
00058 #define PARADEC if(!dec) error("%s:%s %i :: decoder is NULL",__FILE__,__FUNCTION__,__LINE__);
00059
00060
00061
00062
00063 typedef void* (kickoff)(void*);
00064
00065 Channel::Channel() {
00066 func("Channel::Channel()");
00067 volume = 1.0;
00068 speed = 100;
00069 time.h = time.m = time.s = 0;
00070 position = time.f = 0.0;
00071 state = 0.0;
00072 playmode = PLAYMODE_PLAY;
00073 opened = false;
00074 on = false;
00075 update = false;
00076 running = false;
00077 quit = true;
00078 idle = true;
00079
00080 _thread_init();
00081
00082
00083 erbapipa = new Pipe(IN_PIPESIZE);
00084 erbapipa->set_output_type("mix_int16_to_int32");
00085
00086 erbapipa->set_block(true,true);
00087 erbapipa->set_block_timeout(400,200);
00088
00089 playlist = new Playlist();
00090 dec = NULL;
00091 fill_prev_smp = true;
00092 lcd[0] = '\0';
00093 }
00094
00095 Channel::~Channel() {
00096 func("Channel::~Channel()");
00097
00098
00099
00100
00101 quit = true;
00102
00103 while(running) jsleep(0,20);
00104
00105
00106
00107 delete erbapipa;
00108 delete playlist;
00109 if(dec) delete dec;
00110
00111 _thread_destroy();
00112 }
00113
00114 void Channel::run() {
00115
00116 IN_DATATYPE *buff;
00117 lock();
00118 func("InChanThread! here i am");
00119 running = true;
00120 unlock();
00121 signal();
00122
00123 quit = false;
00124
00125 while(!quit) {
00126
00127 if(on) {
00128 idle = false;
00129 PARADEC
00130 dec->lock();
00131
00132
00133
00134
00135
00136
00137
00138
00139 buff = dec->get_audio();
00140 dec->unlock();
00141
00142
00143
00144 if(buff) {
00145 buff = resample(buff);
00146
00147
00148
00149 erbapipa->write(frames*2,buff);
00150
00151
00152 if(dec->seekable) state = upd_time();
00153
00154 } else
00155 if(dec->eos) upd_eos();
00156 else if(dec->err) upd_err();
00157 else {
00158
00159
00160 jsleep(0,20);
00161 }
00162 } else {
00163
00164
00165 idle = true;
00166 jsleep(0,20);
00167 }
00168
00169 }
00170 running = false;
00171 }
00172
00173 IN_DATATYPE *Channel::resample(IN_DATATYPE *audio) {
00174
00175
00176
00177 if(fill_prev_smp) {
00178 prev_smp[0] = audio[0];
00179 prev_smp[1] = audio[1];
00180 prev_smp[2] = audio[2];
00181 prev_smp[3] = audio[3];
00182 fill_prev_smp = false;
00183
00184 }
00185
00186 frames = dec->frames;
00187 frames = (*munch)(buffo,audio,prev_smp,frames,volume);
00188
00189
00190
00191 prev_smp[0] = audio[dec->frames-4];
00192 prev_smp[1] = audio[dec->frames-3];
00193 prev_smp[2] = audio[dec->frames-2];
00194 prev_smp[3] = audio[dec->frames-1];
00195
00196 return(buffo);
00197 }
00198
00199 bool Channel::play() {
00200 if(on) return(true);
00201
00202 if(!running) {
00203 error(_("%i:%s %s channel thread not launched"),
00204 __LINE__,__FILE__,__FUNCTION__);
00205 return(false);
00206 }
00207
00208 if(!opened) {
00209 Url *url;
00210 warning(_("Channel::play() : no song loaded"));
00211 url = (Url*) playlist->selected();
00212 if(!url) {
00213 warning(_("Channel::play() : no song selected in playlist"));
00214 url = (Url*)playlist->begin();
00215 if(!url) {
00216 error(_("Channel::play() : playlist is void"));
00217 return(false);
00218 }
00219 }
00220
00221 if( !load( url->path ) ) {
00222 error(_("Channel::play() : can't load %s"),url->path);
00223 return(false);
00224 } else url->sel(true);
00225 }
00226
00227 if(time.f!=position) {
00228 pos(position);
00229 } else fill_prev_smp = true;
00230
00231 on = true;
00232 return(on);
00233 }
00234
00235 bool Channel::stop() {
00236
00237 on = false;
00238 if(opened) {
00239
00240 pos(0.0);
00241 state = 0.0;
00242 erbapipa->flush();
00243 fill_prev_smp = true;
00244 }
00245 return(!on);
00246 }
00247
00248 int Channel::load(char *file) {
00249 MuseDec *ndec = NULL;
00250 char tmp[256];
00251 int res;
00252
00253
00254
00255
00256 hstream cod = HS_NONE;
00257
00258
00259
00260 snprintf(tmp,256,"%s",file);
00261
00262 if (strstr(file, "http://")) {
00263 cod = stream_detect(file);
00264 }
00265
00266 if(strncasecmp(file+strlen(file)-4,".ogg",4)==0 || cod==HS_OGG) {
00267 #ifdef HAVE_VORBIS
00268 func("creating Ogg decoder");
00269 ndec = new MuseDecOgg();
00270 #else
00271 error(_("Can't open OggVorbis (support not compiled)"));
00272 #endif
00273 }
00274 if(strncasecmp(file+strlen(file)-4,".mp3",4)==0 || cod==HS_MP3) {
00275 func("creating Mp3 decoder");
00276 ndec = new MuseDecMp3();
00277 }
00278
00279 if(strncasecmp(file+strlen(file)-4,".wav",4)==0
00280 || strncasecmp(file+strlen(file)-4,".aif",4)==0
00281 || strncasecmp(file+strlen(file)-5,".aiff",4)==0
00282 || strncasecmp(file+strlen(file)-4,".snd",4)==0
00283 || strncasecmp(file+strlen(file)-3,".au",4)==0
00284 || strncasecmp(file+strlen(file)-4,".raw",4)==0
00285 || strncasecmp(file+strlen(file)-4,".paf",4)==0
00286 || strncasecmp(file+strlen(file)-4,".iff",4)==0
00287 || strncasecmp(file+strlen(file)-4,".svx",4)==0
00288 || strncasecmp(file+strlen(file)-3,".sf",4)==0
00289 || strncasecmp(file+strlen(file)-4,".voc",4)==0
00290 || strncasecmp(file+strlen(file)-4,".w64",4)==0
00291 || strncasecmp(file+strlen(file)-4,".pvf",4)==0
00292 || strncasecmp(file+strlen(file)-3,".xi",4)==0
00293 || strncasecmp(file+strlen(file)-4,".htk",4)==0
00294 || strncasecmp(file+strlen(file)-4,".mat",4)==0
00295 ) {
00296 #ifdef HAVE_SNDFILE
00297 func("creating LibSndFile decoder");
00298 ndec = new MuseDecSndFile();
00299 #else
00300 error(_("Can't open sound file (support not compiled)"));
00301 #endif
00302 }
00303
00304 if(strncasecmp(file,"jack://",7)==0) {
00305 #ifdef HAVE_JACK
00306 func("creating Jack Audio Daemon input client");
00307
00308
00309
00310
00311 ndec = new MuseDecJack();
00312
00313 snprintf(tmp,256,"MuSE_in_%s",&file[7]);
00314
00315 #else
00316 error(_("Jack audio daemon support is not compiled in this version of MuSE"));
00317 #endif
00318 }
00319
00320 if(!ndec) {
00321 error(_("Can't open %s (unrecognized extension)"),file);
00322 return(0);
00323 }
00324
00325 lock();
00326
00327 ndec->lock();
00328 res = ndec->load(tmp);
00329 ndec->unlock();
00330
00331 if(!res) {
00332 error(_("decoder load returns error"),file);
00333 unlock();
00334 delete ndec;
00335 return(0);
00336 }
00337
00338 res = set_resampler(ndec);
00339
00340 if(!res) {
00341 error(_("invalid input samplerate %u"),ndec->samplerate);
00342 unlock();
00343 delete ndec;
00344 return(0);
00345 }
00346
00347
00348
00349
00350 if(dec) delete dec;
00351 dec = ndec;
00352 opened = true;
00353
00354 res = (dec->seekable)?1:2;
00355 seekable = (res==1) ? true : false;
00356 state = 0.0;
00357
00358 unlock();
00359
00360 notice(_("loaded %s"),file);
00361 if(dec->bitrate)
00362 notice("%s %s %iHz %s %iKb/s",
00363 dec->name,
00364 (dec->seekable) ? "file" : "stream",
00365 dec->samplerate,
00366 (dec->channels==1) ? "mono" : "stereo",
00367 dec->bitrate);
00368 else
00369 notice("%s %s %iHz %s",
00370 dec->name,
00371 (dec->seekable) ? "file" : "stream",
00372 dec->samplerate,
00373 (dec->channels==1) ? "mono" : "stereo");
00374
00375 return res;
00376 }
00377
00378 bool Channel::pos(float pos) {
00379 PARADEC
00380 if(!dec->seekable) return false;
00381 pos = (pos<0.0) ? 0.0 : (pos>1.0) ? 1.1 : pos;
00382 dec->lock();
00383 if(!dec->seek(pos))
00384 error(_("error seeking decoder position to %f"),position);
00385 else
00386 position = time.f = pos;
00387 dec->unlock();
00388 return true;
00389 }
00390
00391 void Channel::clean() {
00392 on = false;
00393
00394
00395
00396 opened = false;
00397 while(!idle) jsleep(0,20);
00398 if(dec) delete dec;
00399 dec = NULL;
00400 }
00401
00402 bool Channel::set_resampler(MuseDec *ndec) {
00403 switch(ndec->samplerate) {
00404 case 44100:
00405 if(ndec->channels==2) munch = resample_stereo_44;
00406 else munch = resample_mono_44;
00407 break;
00408 case 32000:
00409 if(ndec->channels==2) munch = resample_stereo_32;
00410 else munch = resample_mono_32;
00411 break;
00412 case 22050:
00413 if(ndec->channels==2) munch = resample_stereo_22;
00414 else munch = resample_mono_22;
00415 break;
00416 case 16000:
00417 if(ndec->channels==2) munch = resample_stereo_16;
00418 else munch = resample_mono_16;
00419 break;
00420 default:
00421 warning(_("Can't mix sound at %uhz"),
00422 ndec->samplerate);
00423 return(false);
00424 }
00425 return(true);
00426 }
00427
00428
00429 float Channel::upd_time() {
00430 PARADEC
00431 float res;
00432
00433
00434 res = (float)dec->framepos/(float)dec->frametot;
00435
00436
00437
00438
00439 time.f = res;
00440 secs = dec->framepos / dec->fps;
00441
00442 if(secs>3600) {
00443 time.h = (int) secs / 3600;
00444 secs -= time.h*3600;
00445 } else time.h = 0;
00446 if(secs>60) {
00447 time.m = (int) secs / 60;
00448 secs -= time.m*60;
00449 } else time.m = 0;
00450 time.s = (int) secs;
00451 update = true;
00452
00453
00454 return(res);
00455 }
00456
00457 void Channel::skip() {
00458 switch(playmode) {
00459 case PLAYMODE_PLAY:
00460 stop();
00461 break;
00462 case PLAYMODE_LOOP:
00463 pos(0.0);
00464 break;
00465 case PLAYMODE_CONT:
00466 Url *n;
00467 stop();
00468 n = (Url*)playlist->selected();
00469 if(n) do {
00470 n->sel(false); n = (Url*)n->next;
00471 if(!n) n = (Url*)playlist->begin();
00472 if(!n) break;
00473 n->sel(true);
00474 } while( ! load(n->path) );
00475 if(n) {
00476 play();
00477 update = true;
00478 }
00479 break;
00480 default: break;
00481 }
00482 }
00483
00484
00485 void Channel::upd_eos() {
00486 PARADEC
00487 if(!dec->eos) return;
00488 func(_("End of %s on %s playing for %i:%i:%i"),
00489 (seekable)?"stream":"file",dec->name,
00490 time.h,time.m,time.s);
00491 skip();
00492 dec->eos = false;
00493 }
00494
00495 void Channel::upd_err() {
00496 PARADEC
00497 if(!dec->err) return;
00498 error(_("error on %s, skipping %s"),
00499 dec->name,(seekable)?_("stream"):_("file"));
00500 report();
00501 skip();
00502 dec->err = false;
00503 }
00504
00505
00506
00507 LiveIn::LiveIn() {
00508 on = false;
00509 gotin = NULL;
00510 }
00511
00512 void LiveIn::init(int smpr, int chans, int *thedsp) {
00513 dsp = thedsp;
00514 sample_rate = smpr;
00515 channels = chans;
00516
00517
00518
00519
00520
00521
00522 gotin = (IN_DATATYPE*)malloc((MIX_CHUNK*4) +128);
00523 }
00524
00525 LiveIn::~LiveIn() {
00526 if(gotin) free(gotin);
00527 }
00528
00529 int LiveIn::mix(int *mixpcm) {
00530 int res;
00531
00532 res = get_audio();
00533 mixxx_stereo_44_novol(mixpcm,gotin,res);
00534
00535 return(res);
00536 }
00537
00538
00539 int LiveIn::get_audio() {
00540 int res;
00541
00542 do {res = read(*dsp,gotin,MIX_CHUNK*4);} while (res==-1 && errno==EINTR);
00543 return(res/4);
00544 }
00545
00546
00547
00548
00549 void Channel::_thread_init() {
00550
00551 func("Channel::thread_init()");
00552 if(pthread_mutex_init (&_mutex,NULL) == -1)
00553 error("error initializing POSIX thread mutex");
00554 if(pthread_cond_init (&_cond, NULL) == -1)
00555 error("error initializing POSIX thread condition");
00556 if(pthread_attr_init (&_attr) == -1)
00557 error("error initializing POSIX thread attribute");
00558
00559
00560
00561 pthread_attr_setdetachstate(&_attr,PTHREAD_CREATE_DETACHED);
00562
00563 }
00564
00565 void Channel::_thread_destroy() {
00566 opened = false;
00567
00568
00569
00570 while(running) {
00571 signal();
00572 lock(); unlock();
00573 }
00574
00575 if(pthread_mutex_destroy(&_mutex) == -1)
00576 error("error destroying POSIX thread mutex");
00577 if(pthread_cond_destroy(&_cond) == -1)
00578 error("error destroying POSIX thread condition");
00579 if(pthread_attr_destroy(&_attr) == -1)
00580 error("error destroying POSIX thread attribute");
00581 }
00582
00583
00584
00585 void Channel::report() {
00586
00587 func("Channel | %s | %s | %s | %s |",
00588 (opened)?"opened":" ",
00589 (running)?"running":" ",
00590 (on)?"on":"off",
00591 (seekable)?"seekable":" ");
00592
00593 func("vol %.2f pos %.2f lcd[%s]",volume,position,lcd);
00594 func("state %.2f playmode %s",state,
00595 (playmode==PLAYMODE_PLAY) ? "PLAY" :
00596 (playmode==PLAYMODE_LOOP) ? "LOOP" :
00597 (playmode==PLAYMODE_CONT) ? "CONT" :
00598 "ERROR");
00599 if (dec) {
00600 func("time: %i:%i:%i framepos %i frametot %i",
00601 time.h, time.m, time.s, dec->framepos,dec->frametot);
00602 func("samplerate %i channels %i bitrate %i",
00603 dec->samplerate,dec->channels,dec->bitrate);
00604 func("frames (16bit) %i",dec->frames);
00605 } else {
00606 func("time: %i:%i:%i ", time.h, time.m, time.s);
00607 }
00608 }
00609