static void snd_fill_fifo(struct despotify_session* ds) { if (ds->dlabort) { while (ds->dlstate == DL_FILLING_BUSY) { DSFYDEBUG("dlstate = %d. waiting...\n", ds->dlstate); shortsleep(); } ds->dlstate = DL_DRAINING; return; } switch (ds->dlstate) { case DL_DRAINING: if (ds->fifo->totbytes < ds->fifo->watermark ) { DSFYDEBUG("Low on data (%d / %d), fetching another channel\n", ds->fifo->totbytes, ds->fifo->maxbytes); DSFYDEBUG("dlstate = DL_FILLING_BUSY\n"); ds->dlstate = DL_FILLING_BUSY; despotify_snd_read_stream(ds); } break; case DL_FILLING: if (ds->fifo->totbytes < (ds->fifo->maxbytes - SUBSTREAM_SIZE)) { DSFYDEBUG("dlstate = DL_FILLING_BUSY\n"); ds->dlstate = DL_FILLING_BUSY; despotify_snd_read_stream(ds); } else { DSFYDEBUG("buffer filled. setting dlstate DL_DRAINING\n"); ds->dlstate = DL_DRAINING; } break; } }
/* This function stops the player thread */ int snd_stop (struct despotify_session *ds) { int ret = 0; DSFYDEBUG ("Entering with arg %p. dl state is %d\n", ds, ds->dlstate); if (ds->dlstate < DL_DRAINING) ds->dlabort = true; while (ds->dlstate == DL_FILLING_BUSY) { DSFYDEBUG("dlstate = %d. waiting...\n", ds->dlstate); shortsleep(); } /* Don't request more data in pcm_read(), even if the buffer gets low */ DSFYDEBUG("dlstate = DL_DRAINING\n"); ds->dlstate = DL_DRAINING; pthread_mutex_lock (&ds->fifo->lock); /* free the ogg fifo */ while (ds->fifo->start) { struct ds_snd_buffer* b = ds->fifo->start; ds->fifo->start = ds->fifo->start->next; free(b->ptr); free(b); } ds->fifo->start = NULL; ds->fifo->end = NULL; /* Reset the session */ snd_reset(ds); ds->dlabort = false; pthread_mutex_unlock (&ds->fifo->lock); return ret; }
int snd_get_pcm(struct despotify_session* ds, struct ds_pcm_data* pcm) { if (!ds || !ds->fifo || !ds->fifo->start) { pcm->len = 0; shortsleep(); return 0; } /* top up fifo */ snd_fill_fifo(ds); if (!ds->vf) { DSFYDEBUG ("Initializing vorbisfile struct\n"); /* Allocate Vorbis struct */ ds->vf = calloc(1, sizeof (OggVorbis_File)); if (!ds->vf) return -1; /* Initialize Vorbis struct with the appropriate callbacks */ ov_callbacks callbacks; callbacks.read_func = snd_ov_read_callback; callbacks.seek_func = seek_func; callbacks.close_func = NULL; callbacks.tell_func = NULL; /* Now call ov_open_callbacks(). This will trigger the read_func */ _DSFYDEBUG("Calling ov_open_callbacks()\n"); int ret = ov_open_callbacks(ds, ds->vf, NULL, 0, callbacks); if (ret) { DSFYfree(ds->vf); DSFYDEBUG("ov_open_callbacks(): error %d (%s)\n", ret, ret == OV_ENOTVORBIS? "not Vorbis": ret == OV_EBADHEADER? "bad header": "unknown, check <vorbis/codec.h>") return ret * 10; } }
int main( int argc, char*argv[] ) { int c,ret; char *port = FCE_DEFAULT_PORT_STRING; char *host = "localhost"; int delay_between_events = 1000; int event_code = FCE_FILE_MODIFY; char pathbuff[1024]; int duration_in_seconds = 0; // TILL ETERNITY char target[256]; char *path = getcwd( pathbuff, sizeof(pathbuff) ); // FULLSPEED TEST IS "-s 1001" -> delay is 0 -> send packets without pause while ((c = getopt(argc, argv, "d:e:h:p:P:s:")) != -1) { switch(c) { case '?': fprintf(stdout, "%s: [ -p Port -h Listener1 [ -h Listener2 ...] -P path -s Delay_between_events_in_us -e event_code -d Duration ]\n", argv[0]); exit(1); break; case 'd': duration_in_seconds = atoi(optarg); break; case 'e': event_code = atoi(optarg); break; case 'h': host = strdup(optarg); break; case 'p': port = strdup(optarg); break; case 'P': path = strdup(optarg); break; case 's': delay_between_events = atoi(optarg); break; } } sprintf(target, "%s:%s", host, port); if (fce_add_udp_socket(target) != 0) return 1; int ev_cnt = 0; time_t start_time = time(NULL); time_t end_time = 0; if (duration_in_seconds) end_time = start_time + duration_in_seconds; while (1) { time_t now = time(NULL); if (now > start_time) { start_time = now; fprintf( stdout, "%d events/s\n", ev_cnt ); ev_cnt = 0; } if (end_time && now >= end_time) break; register_fce( path, 0, event_code ); ev_cnt++; shortsleep( delay_between_events ); } }