void Ut_TrackedVariantTests::trackerSignalEmited () { testClass tv(""); QObject::connect(&tv, SIGNAL(changed()), this, SLOT(catchsignal())); tv.emitTestSignal(); QVERIFY(cnt != 0); }
void Ut_ProfileValueTests::profilevalueNotifyValue() { #ifdef HAVE_LIBPROFILE cnt = 0; QProfileValue pv("ringing.alert.volume"); QObject::connect(&pv, SIGNAL(changed()), this, SLOT( catchsignal() )); QStringList list; list << "general" << "silent"; QString profile = profile_get_profile(); QProfileValue::notifyValue( profile.toAscii(), "ringing.alert.volume", 0, 0, &pv); QVERIFY( cnt ); cnt = 0; QProfileValue::notifyValue( profile.toAscii(), "system.sound.level", 0, 0, &pv); QVERIFY( !cnt ); if (profile == list.at(0)) profile = list.at(1); else profile = list.at(0); QProfileValue::notifyValue( profile.toAscii(), "system.sound.level", 0, 0, &pv); QVERIFY( !cnt ); #endif }
int main(int argc, char **argv) { int i = 0; int fp; #ifdef f32c setup_f32c(); maxfiles = MAXFILES; #else catchsignal(); #endif startfp(); /* start up the floating point hardware */ setup_fb(); /* video framebuffer */ #ifndef f32c setupfiles(argc,argv); setupmyterm(); /* set up files after processing files */ #endif program = 0; clear(); prints("Rabbit BASIC version 2.1.3 (built " __DATE__ ")\n"); if(setexit() == ERR_RESET){ drop_fns(); execute(); /* execute the line */ } drop_fns(); docont(); stocurlin=0; /* say we are in immeadiate mode */ if(cursor) /* put cursor on a blank line */ prints( (char *)nl); if (firstrun && ( #ifdef f32c (fp = open("d:autoexec.bas",0)) > 0 || #endif (fp = open("autoexec.bas",0)) > 0)) { firstrun = 0; readfi(fp, 0, 0); close(fp); clear(); if (program) { stocurlin=program; point= program->lin; elsecount=0; execute(); } } firstrun = 0; prints("Ready\n"); for(;;){ do{ trapped=0; line[0] = '>'; line[1] = 0; VOID edit( (ival)1, (ival)1, (ival)0); }while( trapped || ( !(i=compile(1, nline, 0)) && !linenumber)); if(!linenumber) break; insert(i); } if(inserted){ inserted=0; clear(); closeall(); } #ifdef MSDOS lcount = 0; #endif clr_stack(bstack); /* reset the gosub stack */ bstack = estack = 0; if(str_used) /* free any spare strings */ FREE_STR(str_used); trap_env.e_stolin = 0; /* disable error traps */ intrap=0; /* say we are not in the error trap */ trapped=0; /* say we haven't got a cntrl-c */ cursor=0; /* cursor is at start of line */ elsecount=0; /* disallow elses as terminators */ point=nline; /* start executing at start of input line */ stocurlin=0; /* start of current line is null- see 'next' */ execute(); /* execute the line */ return(-1); /* see note below */ }
void buffer_loop(audio_output_t *ao, sigset_t *oldsigset) { int bytes, outbytes; int my_fd = buffermem->fd[XF_READER]; txfermem *xf = buffermem; int done = FALSE; int preload; catchsignal (SIGINT, catch_interrupt); catchsignal (SIGUSR1, catch_usr1); sigprocmask (SIG_SETMASK, oldsigset, NULL); xfermem_putcmd(my_fd, XF_CMD_WAKEUP); debug("audio output: waiting for cap requests"); /* wait for audio setup queries */ while(1) { int cmd; cmd = xfermem_block(XF_READER, xf); if(cmd == XF_CMD_AUDIOCAP) { ao->rate = xf->rate; ao->channels = xf->channels; ao->format = ao->get_formats(ao); debug3("formats for %liHz/%ich: 0x%x", ao->rate, ao->channels, ao->format); xf->format = ao->format; xfermem_putcmd(my_fd, XF_CMD_AUDIOCAP); } else if(cmd == XF_CMD_WAKEUP) { debug("got wakeup... leaving config mode"); xfermem_putcmd(buffermem->fd[XF_READER], XF_CMD_WAKEUP); break; } else { error1("unexpected command %i", cmd); return; } } /* Fill complete buffer on first run before starting to play. * Live mp3 streams constantly approach buffer underrun otherwise. [dk] */ preload = (int)(param.preload*xf->size); if(preload > xf->size) preload = xf->size; if(preload < 0) preload = 0; for (;;) { if (intflag) { debug("handle intflag... flushing"); intflag = FALSE; ao->flush(ao); /* Either prepare for waiting or empty buffer now. */ if(!xf->justwait) xf->readindex = xf->freeindex; else { int cmd; debug("Prepare for waiting; draining command queue. (There's a lot of wakeup commands pending, usually.)"); do { cmd = xfermem_getcmd(my_fd, FALSE); /* debug1("drain: %i", cmd); */ } while(cmd > 0); } if(xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP); } if (usr1flag) { debug("handling usr1flag"); usr1flag = FALSE; /* close and re-open in order to flush * the device's internal buffer before * changing the sample rate. [OF] */ /* writer must block when sending SIGUSR1 * or we will lose all data processed * in the meantime! [dk] */ xf->readindex = xf->freeindex; /* We've nailed down the new starting location - * writer is now safe to go on. [dk] */ if (xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP); ao->rate = xf->rate; ao->channels = xf->channels; ao->format = xf->format; if (reset_output(ao) < 0) { error1("failed to reset audio: %s", strerror(errno)); exit(1); } } if ( (bytes = xfermem_get_usedspace(xf)) < outburst ) { /* if we got a buffer underrun we first * fill 1/8 of the buffer before continue/start * playing */ if (preload < xf->size>>3) preload = xf->size>>3; if(preload < outburst) preload = outburst; } debug1("bytes: %i", bytes); if(xf->justwait || bytes < preload) { int cmd; if (done && !bytes) { break; } if(xf->justwait || !done) { /* Don't spill into errno check below. */ errno = 0; cmd = xfermem_block(XF_READER, xf); debug1("got %i", cmd); switch(cmd) { /* More input pending. */ case XF_CMD_WAKEUP_INFO: continue; /* Yes, we know buffer is low but * know we don't care. */ case XF_CMD_WAKEUP: break; /* Proceed playing. */ case XF_CMD_ABORT: /* Immediate end, discard buffer contents. */ return; /* Cleanup happens outside of buffer_loop()*/ case XF_CMD_TERMINATE: /* Graceful end, playing stuff in buffer and then return. */ debug("going to terminate"); done = TRUE; break; case XF_CMD_RESYNC: debug("ordered resync"); if (param.outmode == DECODE_AUDIO) ao->flush(ao); xf->readindex = xf->freeindex; if (xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP); continue; break; case -1: if(intflag || usr1flag) /* Got signal, handle it at top of loop... */ { debug("buffer interrupted"); continue; } if(errno) error1("Yuck! Error in buffer handling... or somewhere unexpected: %s", strerror(errno)); done = TRUE; xf->readindex = xf->freeindex; xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE); break; default: fprintf(stderr, "\nEh!? Received unknown command 0x%x in buffer process.\n", cmd); } } } /* Hack! The writer issues XF_CMD_WAKEUP when first adjust * audio settings. We do not want to lower the preload mark * just yet! */ if (xf->justwait || !bytes) continue; preload = outburst; /* set preload to lower mark */ if (bytes > xf->size - xf->readindex) bytes = xf->size - xf->readindex; if (bytes > outburst) bytes = outburst; /* The output can only take multiples of framesize. */ bytes -= bytes % ao->framesize; debug("write"); outbytes = flush_output(ao, (unsigned char*) xf->data + xf->readindex, bytes); if(outbytes < bytes) { if(outbytes < 0) outbytes = 0; if(!intflag && !usr1flag) { error1("Ouch ... error while writing audio data: %s", strerror(errno)); /* * done==TRUE tells writer process to stop * sending data. There might be some latency * involved when resetting readindex to * freeindex so we might need more than one * cycle to terminate. (The number of cycles * should be finite unless I managed to mess * up something. ;-) [dk] */ done = TRUE; xf->readindex = xf->freeindex; xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE); } else debug("buffer interrupted"); } bytes = outbytes; xf->readindex = (xf->readindex + bytes) % xf->size; if (xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP); } }
int main(int sys_argc, char ** sys_argv) { int result; char end_of_files = FALSE; long parr; char *fname; int libpar = 0; mpg123_pars *mp; #if !defined(WIN32) && !defined(GENERIC) struct timeval start_time; #endif aux_out = stdout; /* Need to initialize here because stdout is not a constant?! */ #if defined (WANT_WIN32_UNICODE) if(win32_cmdline_utf8(&argc, &argv) != 0) { error("Cannot convert command line to UTF8!"); safe_exit(76); } #else argv = sys_argv; argc = sys_argc; #endif #if defined (WANT_WIN32_SOCKETS) win32_net_init(); #endif /* Extract binary and path, take stuff before/after last / or \ . */ if((prgName = strrchr(argv[0], '/')) || (prgName = strrchr(argv[0], '\\'))) { /* There is some explicit path. */ prgName[0] = 0; /* End byte for path. */ prgName++; binpath = argv[0]; } else { prgName = argv[0]; /* No path separators there. */ binpath = NULL; /* No path at all. */ } /* Need to initialize mpg123 lib here for default parameter values. */ result = mpg123_init(); if(result != MPG123_OK) { error1("Cannot initialize mpg123 library: %s", mpg123_plain_strerror(result)); safe_exit(77); } cleanup_mpg123 = TRUE; mp = mpg123_new_pars(&result); /* This may get leaked on premature exit(), which is mainly a cosmetic issue... */ if(mp == NULL) { error1("Crap! Cannot get mpg123 parameters: %s", mpg123_plain_strerror(result)); safe_exit(78); } /* get default values */ mpg123_getpar(mp, MPG123_DOWN_SAMPLE, &parr, NULL); param.down_sample = (int) parr; mpg123_getpar(mp, MPG123_RVA, ¶m.rva, NULL); mpg123_getpar(mp, MPG123_DOWNSPEED, ¶m.halfspeed, NULL); mpg123_getpar(mp, MPG123_UPSPEED, ¶m.doublespeed, NULL); mpg123_getpar(mp, MPG123_OUTSCALE, ¶m.outscale, NULL); mpg123_getpar(mp, MPG123_FLAGS, &parr, NULL); mpg123_getpar(mp, MPG123_INDEX_SIZE, ¶m.index_size, NULL); param.flags = (int) parr; param.flags |= MPG123_SEEKBUFFER; /* Default on, for HTTP streams. */ mpg123_getpar(mp, MPG123_RESYNC_LIMIT, ¶m.resync_limit, NULL); mpg123_getpar(mp, MPG123_PREFRAMES, ¶m.preframes, NULL); #ifdef OS2 _wildcard(&argc,&argv); #endif while ((result = getlopt(argc, argv, opts))) switch (result) { case GLO_UNKNOWN: fprintf (stderr, "%s: Unknown option \"%s\".\n", prgName, loptarg); usage(1); case GLO_NOARG: fprintf (stderr, "%s: Missing argument for option \"%s\".\n", prgName, loptarg); usage(1); } /* Do this _after_ parameter parsing. */ check_locale(); /* Check/set locale; store if it uses UTF-8. */ if(param.list_cpu) { const char **all_dec = mpg123_decoders(); printf("Builtin decoders:"); while(*all_dec != NULL){ printf(" %s", *all_dec); ++all_dec; } printf("\n"); mpg123_delete_pars(mp); return 0; } if(param.test_cpu) { const char **all_dec = mpg123_supported_decoders(); printf("Supported decoders:"); while(*all_dec != NULL){ printf(" %s", *all_dec); ++all_dec; } printf("\n"); mpg123_delete_pars(mp); return 0; } if(param.gain != -1) { warning("The parameter -g is deprecated and may be removed in the future."); } if (loptind >= argc && !param.listname && !param.remote) usage(1); /* Init audio as early as possible. If there is the buffer process to be spawned, it shouldn't carry the mpg123_handle with it. */ bufferblock = mpg123_safe_buffer(); /* Can call that before mpg123_init(), it's stateless. */ if(init_output(&ao) < 0) { error("Failed to initialize output, goodbye."); mpg123_delete_pars(mp); return 99; /* It's safe here... nothing nasty happened yet. */ } have_output = TRUE; /* ========================================================================================================= */ /* Enterning the leaking zone... we start messing with stuff here that should be taken care of when leaving. */ /* Don't just exit() or return out... */ /* ========================================================================================================= */ httpdata_init(&htd); #if !defined(WIN32) && !defined(GENERIC) if (param.remote) { param.verbose = 0; param.quiet = 1; param.flags |= MPG123_QUIET; } #endif /* Set the frame parameters from command line options */ if(param.quiet) param.flags |= MPG123_QUIET; #ifdef OPT_3DNOW if(dnow != 0) param.cpu = (dnow == SET_3DNOW) ? "3dnow" : "i586"; #endif if(param.cpu != NULL && (!strcmp(param.cpu, "auto") || !strcmp(param.cpu, ""))) param.cpu = NULL; if(!( MPG123_OK == (result = mpg123_par(mp, MPG123_VERBOSE, param.verbose, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_FLAGS, param.flags, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_DOWN_SAMPLE, param.down_sample, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_RVA, param.rva, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_FORCE_RATE, param.force_rate, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_DOWNSPEED, param.halfspeed, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_UPSPEED, param.doublespeed, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_ICY_INTERVAL, 0, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_RESYNC_LIMIT, param.resync_limit, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_TIMEOUT, param.timeout, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_OUTSCALE, param.outscale, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_PREFRAMES, param.preframes, 0)) )) { error2("Cannot set library parameter %i: %s", libpar, mpg123_plain_strerror(result)); safe_exit(45); } if (!(param.listentry < 0) && !param.quiet) print_title(stderr); /* do not pollute stdout! */ { long default_index; mpg123_getpar(mp, MPG123_INDEX_SIZE, &default_index, NULL); if( param.index_size != default_index && (result = mpg123_par(mp, MPG123_INDEX_SIZE, param.index_size, 0.)) != MPG123_OK ) error1("Setting of frame index size failed: %s", mpg123_plain_strerror(result)); } if(param.force_rate && param.down_sample) { error("Down sampling and fixed rate options not allowed together!"); safe_exit(1); } /* Now actually get an mpg123_handle. */ mh = mpg123_parnew(mp, param.cpu, &result); if(mh == NULL) { error1("Crap! Cannot get a mpg123 handle: %s", mpg123_plain_strerror(result)); safe_exit(77); } mpg123_delete_pars(mp); /* Don't need the parameters anymore ,they're in the handle now. */ /* Prepare stream dumping, possibly replacing mpg123 reader. */ if(dump_open(mh) != 0) safe_exit(78); /* Now either check caps myself or query buffer for that. */ audio_capabilities(ao, mh); load_equalizer(mh); #ifdef HAVE_SETPRIORITY if(param.aggressive) { /* tst */ int mypid = getpid(); setpriority(PRIO_PROCESS,mypid,-20); } #endif #if defined (HAVE_SCHED_SETSCHEDULER) && !defined (__CYGWIN__) && !defined (HAVE_WINDOWS_H) /* Cygwin --realtime seems to fail when accessing network, using win32 set priority instead */ /* MinGW may have pthread installed, we prefer win32API */ if (param.realtime) { /* Get real-time priority */ struct sched_param sp; fprintf(stderr,"Getting real-time priority\n"); memset(&sp, 0, sizeof(struct sched_param)); sp.sched_priority = sched_get_priority_min(SCHED_FIFO); if (sched_setscheduler(0, SCHED_RR, &sp) == -1) fprintf(stderr,"Can't get real-time priority\n"); } #endif #ifdef HAVE_WINDOWS_H /* argument "3" is equivalent to realtime priority class */ win32_set_priority( param.realtime ? 3 : param.w32_priority); #endif if(!param.remote) prepare_playlist(argc, argv); #if !defined(WIN32) && !defined(GENERIC) /* Remote mode is special... but normal console and terminal-controlled operation needs to catch the SIGINT. For one it serves for track skip when not in terminal control mode. The more important use being a graceful exit, including telling the buffer process what's going on. */ if(!param.remote) catchsignal (SIGINT, catch_interrupt); #endif if(param.remote) { int ret; ret = control_generic(mh); safe_exit(ret); } #ifdef HAVE_TERMIOS debug1("param.term_ctrl: %i", param.term_ctrl); if(param.term_ctrl) term_init(); #endif if(APPFLAG(MPG123APP_CONTINUE)) frames_left = param.frame_number; while ((fname = get_next_file())) { char *dirname, *filename; int newdir; /* skip_tracks includes the previous one. */ if(skip_tracks) --skip_tracks; if(skip_tracks) { debug("Skipping this track."); continue; } if(param.delay > 0) { /* One should enable terminal control during that sleeping phase! */ if(param.verbose > 2) fprintf(stderr, "Note: pausing %i seconds before next track.\n", param.delay); output_pause(ao); #ifdef WIN32 Sleep(param.delay*1000); #else sleep(param.delay); #endif output_unpause(ao); } if(!APPFLAG(MPG123APP_CONTINUE)) frames_left = param.frame_number; debug1("Going to play %s", strcmp(fname, "-") ? fname : "standard input"); if(intflag || !open_track(fname)) { #ifdef HAVE_TERMIOS /* We need the opportunity to cancel in case of --loop -1 . */ if(param.term_ctrl) term_control(mh, ao); #endif /* No wait for a second interrupt before we started playing. */ if(intflag) break; continue; } if(!param.quiet) fprintf(stderr, "\n"); if(param.index) { if(param.verbose) fprintf(stderr, "indexing...\r"); mpg123_scan(mh); } /* Only trigger a seek if we do not want to start with the first frame. Rationale: Because of libmpg123 sample accuracy, this could cause an unnecessary backwards seek, that even may fail on non-seekable streams. For start frame of 0, we are already at the correct position! */ framenum = 0; if(param.start_frame > 0) framenum = mpg123_seek_frame(mh, param.start_frame, SEEK_SET); if(APPFLAG(MPG123APP_CONTINUE)) param.start_frame = 0; if(framenum < 0) { error1("Initial seek failed: %s", mpg123_strerror(mh)); if(mpg123_errcode(mh) == MPG123_BAD_OUTFORMAT) { fprintf(stderr, "%s", "So, you have trouble getting an output format... this is the matrix of currently possible formats:\n"); print_capabilities(ao, mh); fprintf(stderr, "%s", "Somehow the input data and your choices don't allow one of these.\n"); } mpg123_close(mh); continue; } /* Prinout and xterm title need this, possibly independently. */ newdir = split_dir_file(fname ? fname : "standard input", &dirname, &filename); if (!param.quiet) { if(newdir) fprintf(stderr, "Directory: %s\n", dirname); #ifdef HAVE_TERMIOS /* Reminder about terminal usage. */ if(param.term_ctrl) term_hint(); #endif fprintf(stderr, "Playing MPEG stream %lu of %lu: %s ...\n", (unsigned long)pl.pos, (unsigned long)pl.fill, filename); if(htd.icy_name.fill) fprintf(stderr, "ICY-NAME: %s\n", htd.icy_name.p); if(htd.icy_url.fill) fprintf(stderr, "ICY-URL: %s\n", htd.icy_url.p); } #if !defined(GENERIC) { const char *term_type; term_type = getenv("TERM"); if(term_type && param.xterm_title) { if(!strncmp(term_type,"xterm",5) || !strncmp(term_type,"rxvt",4)) fprintf(stderr, "\033]0;%s\007", filename); else if(!strncmp(term_type,"screen",6)) fprintf(stderr, "\033k%s\033\\", filename); else if(!strncmp(term_type,"iris-ansi",9)) fprintf(stderr, "\033P1.y %s\033\\\033P3.y%s\033\\", filename, filename); fflush(stderr); /* Paranoia: will the buffer buffer the escapes? */ } } #endif /* Rethink that SIGINT logic... */ #if !defined(WIN32) && !defined(GENERIC) #ifdef HAVE_TERMIOS if(!param.term_ctrl) #endif gettimeofday (&start_time, NULL); #endif while(!intflag) { int meta; if(param.frame_number > -1) { debug1("frames left: %li", (long) frames_left); if(!frames_left) { if(APPFLAG(MPG123APP_CONTINUE)) end_of_files = TRUE; break; } } if(!play_frame()) break; if(!param.quiet) { meta = mpg123_meta_check(mh); if(meta & (MPG123_NEW_ID3|MPG123_NEW_ICY)) { if(meta & MPG123_NEW_ID3) print_id3_tag(mh, param.long_id3, stderr); if(meta & MPG123_NEW_ICY) print_icy(mh, stderr); mpg123_meta_free(mh); /* Do not waste memory after delivering. */ } } if(!fresh && param.verbose) { #ifndef NOXFERMEM if (param.verbose > 1 || !(framenum & 0x7)) print_stat(mh,0,xfermem_get_usedspace(buffermem)); #else if(param.verbose > 1 || !(framenum & 0x7)) print_stat(mh,0,0); #endif } #ifdef HAVE_TERMIOS if(!param.term_ctrl) continue; else term_control(mh, ao); #endif } if(!param.smooth && param.usebuffer) buffer_drain(); if(param.verbose) print_stat(mh,0,xfermem_get_usedspace(buffermem)); if(!param.quiet) { double secs; long frank; fprintf(stderr, "\n"); if(mpg123_getstate(mh, MPG123_FRANKENSTEIN, &frank, NULL) == MPG123_OK && frank) fprintf(stderr, "This was a Frankenstein track.\n"); mpg123_position(mh, 0, 0, NULL, NULL, &secs, NULL); fprintf(stderr,"[%d:%02d] Decoding of %s finished.\n", (int)(secs / 60), ((int)secs) % 60, filename); } else if(param.verbose) fprintf(stderr, "\n"); mpg123_close(mh); if (intflag) { if(!skip_or_die(&start_time)) break; intflag = FALSE; #ifndef NOXFERMEM if(!param.smooth && param.usebuffer) buffer_resync(); #endif } if(end_of_files) break; } /* end of loop over input files */ /* Ensure we played everything. */ if(param.smooth && param.usebuffer) { buffer_drain(); buffer_resync(); } if(APPFLAG(MPG123APP_CONTINUE)) { continue_msg("CONTINUE"); } /* Free up memory used by playlist */ if(!param.remote) free_playlist(); safe_exit(0); /* That closes output and restores terminal, too. */ return 0; }
void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset) { int bytes; int my_fd = buffermem->fd[XF_READER]; txfermem *xf = buffermem; int done = FALSE; catchsignal (SIGINT, catch_interrupt); catchsignal (SIGUSR1, catch_usr1); sigprocmask (SIG_SETMASK, oldsigset, NULL); #ifndef NO_DECODE_AUDIO if (param.outmode == DECODE_AUDIO) { if (audio_open(ai) < 0) { perror("audio"); exit(1); } } #endif for (;;) { if (intflag) { intflag = FALSE; #ifndef NO_DECODE_AUDIO if (param.outmode == DECODE_AUDIO) audio_queueflush (ai); #endif xf->readindex = xf->freeindex; if (xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP); } if (usr1flag) { usr1flag = FALSE; /* close and re-open in order to flush * the device's internal buffer before * changing the sample rate. [OF] */ /* writer must block when sending SIGUSR1 * or we will lose all data processed * in the meantime! [dk] */ xf->readindex = xf->freeindex; /* We've nailed down the new starting location - * writer is now safe to go on. [dk] */ if (xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP); #ifndef NO_DECODE_AUDIO if (param.outmode == DECODE_AUDIO) { audio_close (ai); ai->rate = xf->buf[0]; ai->channels = xf->buf[1]; ai->format = xf->buf[2]; if (audio_open(ai) < 0) { sleep(1); /* give em a 2. try */ if (audio_open(ai) < 0) { perror("audio"); exit(1); } } } #endif } if ( (bytes = xfermem_get_usedspace(xf)) < outburst ) { /* if we got a buffer underrun we first * fill 1/8 of the buffer before continue/start * playing */ preload = xf->size>>3; if(preload < outburst) preload = outburst; } if(bytes < preload) { int cmd; if (done && !bytes) { break; } if(!done) { cmd = xfermem_block(XF_READER, xf); switch(cmd) { /* More input pending. */ case XF_CMD_WAKEUP_INFO: continue; /* Yes, we know buffer is low but * know we don't care. */ case XF_CMD_WAKEUP: break; /* Proceed playing. */ case XF_CMD_TERMINATE: /* Proceed playing without * blocking any further. */ done=TRUE; break; case -1: if(errno==EINTR) continue; perror("Yuck! Error in buffer handling..."); done = TRUE; xf->readindex = xf->freeindex; xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE); break; default: fprintf(stderr, "\nEh!? Received unknown command 0x%x in buffer process. Tell Daniel!\n", cmd); } } } preload = outburst; /* set preload to lower mark */ if (bytes > xf->size - xf->readindex) bytes = xf->size - xf->readindex; if (bytes > outburst) bytes = outburst; if (param.outmode == DECODE_FILE) bytes = write(OutputDescriptor, xf->data + xf->readindex, bytes); #ifndef NO_DECODE_AUDIO else if (param.outmode == DECODE_AUDIO) bytes = audio_play_samples(ai, (unsigned char *) (xf->data + xf->readindex), bytes); #endif if(bytes < 0) { bytes = 0; if(errno != EINTR) { perror("Ouch ... error while writing audio data: "); /* * done==TRUE tells writer process to stop * sending data. There might be some latency * involved when resetting readindex to * freeindex so we might need more than one * cycle to terminate. (The number of cycles * should be finite unless I managed to mess * up something. ;-) [dk] */ done = TRUE; xf->readindex = xf->freeindex; xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE); } } xf->readindex = (xf->readindex + bytes) % xf->size; if (xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP); }