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