static void *asap_play_thread(void *arg) { while (thread_run) { static unsigned char buffer[BUFFERED_BLOCKS * (BITS_PER_SAMPLE / 8) * 2]; int buffered_bytes; if (generated_eof) { xmms_usleep(10000); continue; } if (seek_to >= 0) { mod.output->flush(seek_to); ASAP_Seek(asap, seek_to); seek_to = -1; } buffered_bytes = BUFFERED_BLOCKS * channels * (BITS_PER_SAMPLE / 8); buffered_bytes = ASAP_Generate(asap, buffer, buffered_bytes, BITS_PER_SAMPLE == 8 ? ASAPSampleFormat_U8 : ASAPSampleFormat_S16_L_E); if (buffered_bytes == 0) { generated_eof = TRUE; mod.output->buffer_free(); mod.output->buffer_free(); continue; } mod.add_vis_pcm(mod.output->written_time(), BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_LE, channels, buffered_bytes, buffer); while (thread_run && mod.output->buffer_free() < buffered_bytes) xmms_usleep(20000); if (thread_run) mod.output->write_audio(buffer, buffered_bytes); } pthread_exit(NULL); }
static void driver_callback(void *b, int i) { xmp_ip.add_vis_pcm(xmp_ip.output->written_time(), xmp_cfg.force8bit ? FMT_U8 : FMT_S16_NE, xmp_cfg.force_mono ? 1 : 2, i, b); while (xmp_ip.output->buffer_free() < i && playing) usleep(10000); if (playing) xmp_ip.output->write_audio(b, i); }
void process_buffer(size_t num_samples) { int tsamples = num_samples * num_channels; if (!(WavpackGetMode (ctx) & MODE_FLOAT)) { float scaler = (float) (1.0 / ((unsigned int32_t) 1 << (bytes_per_sample * 8 - 1))); float *fptr = (float *) input; int32_t *lptr = input; int cnt = tsamples; while (cnt--) *fptr++ = *lptr++ * scaler; } if (play_gain != 1.0) { float *fptr = (float *) input; int cnt = tsamples; while (cnt--) *fptr++ *= play_gain; } if (tsamples) { float *fptr = (float *) input; short *sptr = (short *) output; int cnt = num_samples, ch; while (cnt--) for (ch = 0; ch < num_channels; ++ch) { int dst; *fptr -= shaping_error [ch]; if (*fptr >= 1.0) dst = 32767; else if (*fptr <= -1.0) dst = -32768; else dst = (int) floor (*fptr * 32768.0); shaping_error [ch] = (float)(dst / 32768.0 - *fptr++); *sptr++ = dst; } } if (EQ_on) iir ((char *) output, tsamples * sizeof(int16_t)); mod->add_vis_pcm(mod->output->written_time(), FMT_S16_NE, num_channels, tsamples * sizeof(int16_t), output); mod->output->write_audio(output, tsamples * sizeof(int16_t)); }
static void *playloop (void *arg) { uint_least8_t *buffer = sidplayer.buffer; int length = sidplayer.bufferSize; while (running) { pthread_mutex_lock (&lib_mutex); (void) sidplayer.lib.play (buffer, length); pthread_mutex_unlock (&lib_mutex); sid_ip.add_vis_pcm (sid_ip.output->written_time(), FMT_S16_LE, 2, length, buffer); while ((sid_ip.output->buffer_free() < length) && running) xmms_usleep(10000); sid_ip.output->write_audio (buffer, length); } }
static void driver_callback(void *b, int i) { #if __AUDACIOUS_PLUGIN_API__ >= 2 play_data.ipb->pass_audio(play_data.ipb, play_data.fmt, play_data.nch, i, b, &play_data.ipb->playing); #else xmp_ip.add_vis_pcm(xmp_ip.output->written_time(), xmp_cfg.force8bit ? FMT_U8 : FMT_S16_NE, xmp_cfg.force_mono ? 1 : 2, i, b); while (xmp_ip.output->buffer_free() < i && play_data.ipb->playing) usleep(10000); if (play_data.ipb->playing) xmp_ip.output->write_audio(b, i); #endif }
static void *play_thread(void *arg) { for (;;) { static #if BITS_PER_SAMPLE == 8 unsigned char #else short int #endif buffer[BUFFERED_BLOCKS * 2]; ASAP_Generate(buffer, buffered_bytes); mod.add_vis_pcm(mod.output->written_time(), BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_NE, channels, buffered_bytes, buffer); while (thread_run && mod.output->buffer_free() < buffered_bytes) xmms_usleep(20000); if (!thread_run) break; mod.output->write_audio(buffer, buffered_bytes); } mod.output->buffer_free(); mod.output->buffer_free(); pthread_exit(NULL); }
static void *mp4Decode(void *args) { FILE* mp4file; pthread_mutex_lock(&mutex); seekPosition = -1; bPlaying = TRUE; if(!(mp4file = fopen(args, "rb"))){ g_print("MP4!AAC - Can't open file\n"); g_free(args); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } mp4_get_file_type(mp4file); fseek(mp4file, 0, SEEK_SET); if(mp4cfg.file_type == FILE_MP4){// We are reading a MP4 file mp4ff_callback_t* mp4cb; mp4ff_t* infile; gint mp4track; mp4cb = getMP4FF_cb(mp4file); if(!(infile = mp4ff_open_read(mp4cb))){ g_print("MP4 - Can't open file\n"); goto end; } if((mp4track = getAACTrack(infile)) < 0){ /* * TODO: check here for others Audio format..... * */ g_print("Unsupported Audio track type\n"); g_free(args); fclose(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ NeAACDecHandle decoder; unsigned char *buffer = NULL; guint bufferSize = 0; gulong samplerate; guchar channels; //guint avgBitrate; //MP4Duration duration; int msDuration; int numSamples; int sampleID = 0; unsigned int framesize; mp4AudioSpecificConfig mp4ASC; gchar *xmmstitle; decoder = NeAACDecOpen(); mp4ff_get_decoder_config(infile, mp4track, &buffer, &bufferSize); if(NeAACDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0){ goto end; } if(buffer){ framesize = 1024; if(NeAACDecAudioSpecificConfig(buffer, bufferSize, &mp4ASC) >= 0){ if(mp4ASC.frameLengthFlag == 1) framesize = 960; if(mp4ASC.sbr_present_flag == 1) framesize *= 2; } g_free(buffer); } if(channels == 0){ g_print("Number of Channels not supported\n"); goto end; } //duration = MP4GetTrackDuration(mp4file, mp4track); //msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, // duration,MP4_MSECS_TIME_SCALE); //msDuration = mp4ff_get_track_duration(infile, mp4track); //printf("%d\n", msDuration); //numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); numSamples = mp4ff_num_samples(infile, mp4track); { float f = 1024.0; if(mp4ASC.sbr_present_flag == 1) f = f * 2.0; msDuration = ((float)numSamples*(float)(f-1.0)/ (float)samplerate)*1000; } xmmstitle = getMP4title(infile, args); mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); mp4_ip.output->flush(0); mp4_ip.set_info(xmmstitle, msDuration, -1, samplerate/1000, channels); g_print("MP4 - %d channels @ %ld Hz\n", channels, samplerate); while(bPlaying){ void* sampleBuffer; faacDecFrameInfo frameInfo; gint rc; if(seekPosition!=-1){ /* duration = MP4ConvertToTrackDuration(mp4file, mp4track, seekPosition*1000, MP4_MSECS_TIME_SCALE); sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); */ float f = 1024.0; if(mp4ASC.sbr_present_flag == 1) f = f * 2.0; sampleID = (float)seekPosition*(float)samplerate/(float)(f-1.0); mp4_ip.output->flush(seekPosition*1000); seekPosition = -1; } buffer=NULL; bufferSize=0; rc = mp4ff_read_sample(infile, mp4track, sampleID++, &buffer, &bufferSize); //g_print("%d/%d\n", sampleID-1, numSamples); if((rc==0) || (buffer== NULL)){ g_print("MP4: read error\n"); sampleBuffer = NULL; sampleID=0; mp4_ip.output->buffer_free(); goto end; }else{ sampleBuffer = NeAACDecDecode(decoder, &frameInfo, buffer, bufferSize); if(frameInfo.error > 0){ g_print("MP4: %s\n", faacDecGetErrorMessage(frameInfo.error)); goto end; } if(buffer){ g_free(buffer); buffer=NULL; bufferSize=0; } while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) xmms_usleep(30000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_NE, channels, frameInfo.samples<<1, sampleBuffer); mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1); if(sampleID >= numSamples){ break; } } while(bPlaying && mp4_ip.output->buffer_playing() && mp4_ip.output->buffer_free()){ xmms_usleep(10000); } end: mp4_ip.output->close_audio(); g_free(args); NeAACDecClose(decoder); if(infile) mp4ff_close(infile); if(mp4cb) g_free(mp4cb); bPlaying = FALSE; fclose(mp4file); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } }else{ // WE ARE READING AN AAC FILE FILE *file = NULL; NeAACDecHandle decoder = 0; guchar *buffer = 0; gulong bufferconsumed = 0; gulong samplerate = 0; guchar channels; gulong buffervalid = 0; TitleInput* input; gchar *temp = g_strdup(args); gchar *ext = strrchr(temp, '.'); gchar *xmmstitle = NULL; NeAACDecConfigurationPtr config; if((file = fopen(args, "rb")) == 0){ g_print("AAC: can't find file %s\n", args); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((decoder = NeAACDecOpen()) == NULL){ g_print("AAC: Open Decoder Error\n"); fclose(file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } config = NeAACDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 0; NeAACDecSetConfiguration(decoder, config); if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ g_print("AAC: error g_malloc\n"); fclose(file); bPlaying = FALSE; NeAACDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ g_print("AAC: Error reading file\n"); g_free(buffer); fclose(file); bPlaying = FALSE; NeAACDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } XMMS_NEW_TITLEINPUT(input); input->file_name = g_basename(temp); input->file_ext = ext ? ext+1 : NULL; input->file_path = temp; if(!strncmp(buffer, "ID3", 3)){ gint size = 0; fseek(file, 0, SEEK_SET); size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; size+=10; fread(buffer, 1, size, file); buffervalid = fread(buffer, 1, BUFFER_SIZE, file); } xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); if(xmmstitle == NULL) xmmstitle = g_strdup(input->file_name); if(temp) g_free(temp); if(input->performer) g_free(input->performer); if(input->album_name) g_free(input->album_name); if(input->track_name) g_free(input->track_name); if(input->genre) g_free(input->genre); g_free(input); bufferconsumed = NeAACDecInit(decoder, buffer, buffervalid, &samplerate, &channels); if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ g_print("AAC: Output Error\n"); g_free(buffer); buffer=0; faacDecClose(decoder); fclose(file); mp4_ip.output->close_audio(); /* if(positionTable){ g_free(positionTable); positionTable=0; } */ g_free(xmmstitle); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } //if(bSeek){ //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); //}else{ mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); //} mp4_ip.output->flush(0); while(bPlaying && buffervalid > 0){ NeAACDecFrameInfo finfo; unsigned long samplesdecoded; char* sample_buffer = NULL; /* if(bSeek && seekPosition!=-1){ fseek(file, positionTable[seekPosition], SEEK_SET); bufferconsumed=0; buffervalid = fread(buffer, 1, BUFFER_SIZE, file); aac_ip.output->flush(seekPosition*1000); seekPosition=-1; } */ if(bufferconsumed > 0){ memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); buffervalid -= bufferconsumed; buffervalid += fread(&buffer[buffervalid], 1, BUFFER_SIZE-buffervalid, file); bufferconsumed = 0; } sample_buffer = NeAACDecDecode(decoder, &finfo, buffer, buffervalid); if(finfo.error){ config = NeAACDecGetCurrentConfiguration(decoder); if(config->useOldADTSFormat != 1){ NeAACDecClose(decoder); decoder = NeAACDecOpen(); config = NeAACDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 1; NeAACDecSetConfiguration(decoder, config); finfo.bytesconsumed=0; finfo.samples = 0; NeAACDecInit(decoder, buffer, buffervalid, &samplerate, &channels); }else{ g_print("FAAD2 Warning %s\n", NeAACDecGetErrorMessage(finfo.error)); buffervalid = 0; } } bufferconsumed += finfo.bytesconsumed; samplesdecoded = finfo.samples; if((samplesdecoded<=0) && !sample_buffer){ g_print("AAC: error sample decoding\n"); continue; } while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ xmms_usleep(10000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_LE, channels, samplesdecoded<<1, sample_buffer); mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); } while(bPlaying && mp4_ip.output->buffer_playing()){ xmms_usleep(10000); } mp4_ip.output->buffer_free(); mp4_ip.output->close_audio(); bPlaying = FALSE; g_free(buffer); NeAACDecClose(decoder); g_free(xmmstitle); fclose(file); seekPosition = -1; /* if(positionTable){ g_free(positionTable); positionTable=0; } */ bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } }
static void * play_loop(void *arg) { nsf_t * nsf = app.nsf; pdebug("nsf : play-thread\n"); if (!app.nsf) { going = FALSE; } pdebug("nsf : going [%s]\n", going ? "Yes" : "No"); app.cur_track = 0; nsf->cur_frame = nsf->cur_frame_end = 0; while (going) { if (nsf->cur_frame >= nsf->cur_frame_end) { int next_track = app.cur_track+1; pdebug("nsf : frame elapsed [%u > %u] -> track #%02d\n", nsf->cur_frame,nsf->cur_frame_end, next_track); if (next_track > app.n_tracks) { pdebug("nsf : reach last song\n"); going = FALSE; break; } SetChangeTrack(next_track, -1); } if (ApplyChangeTrack() < 0) { going = FALSE; break; } if (!app.bufcnt) { /* Run a frame. */ nsf_frame(nsf); apu_process(app.buffer, app.buflen); app.bufptr = app.buffer; app.bufcnt = app.buflen; } if (going) { int tosend = app.bufcnt << 1; while (nosefart_ip.output->buffer_free() < tosend && going) { xmms_usleep(30000); } nosefart_ip.add_vis_pcm(nosefart_ip.output->written_time(), FMT_S16_LE, 1, tosend, app.bufptr); nosefart_ip.output->write_audio(app.bufptr, tosend); tosend >>= 1; app.bufcnt -= tosend; app.bufptr += tosend; } } pdebug("nsf : decoder loop end\n"); SetChangeTrack(0, -1); ApplyChangeTrack(); if (app.nsf) { nsf_free(&app.nsf); app.nsf = nsf = 0; } /* Make sure the output plugin stops prebuffering */ if (nosefart_ip.output) { pdebug("nsf : free audio buffer.\n"); nosefart_ip.output->buffer_free(); } going = FALSE; pdebug("nsf : decode finish\n"); play_thread = 0; pthread_exit(NULL); }
static void *mp4Decode(void *args) { MP4FileHandle mp4file; pthread_mutex_lock(&mutex); seekPosition = -1; bPlaying = TRUE; if(!(mp4file = MP4Read(args, 0))){ mp4cfg.file_type = FILE_AAC; MP4Close(mp4file); }else{ mp4cfg.file_type = FILE_MP4; } if(mp4cfg.file_type == FILE_MP4){ // We are reading a MP4 file gint mp4track; if((mp4track = getAACTrack(mp4file)) < 0){ //TODO: check here for others Audio format..... g_print("Unsupported Audio track type\n"); g_free(args); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ faacDecHandle decoder; unsigned char *buffer = NULL; guint bufferSize = 0; gulong samplerate; guchar channels; guint avgBitrate; MP4Duration duration; gulong msDuration; MP4SampleId numSamples; MP4SampleId sampleID = 1; decoder = faacDecOpen(); MP4GetTrackESConfiguration(mp4file, mp4track, &buffer, &bufferSize); if(!buffer){ g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if(faacDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0){ g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } g_free(buffer); if(channels == 0){ g_print("Number of Channels not supported\n"); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } duration = MP4GetTrackDuration(mp4file, mp4track); msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, duration, MP4_MSECS_TIME_SCALE); numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); mp4_ip.output->flush(0); mp4_ip.set_info(args, msDuration, -1, samplerate/1000, channels); g_print("MP4 - %d channels @ %d Hz\n", channels, samplerate); while(bPlaying){ void* sampleBuffer; faacDecFrameInfo frameInfo; gint rc; if(seekPosition!=-1){ duration = MP4ConvertToTrackDuration(mp4file, mp4track, seekPosition*1000, MP4_MSECS_TIME_SCALE); sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); mp4_ip.output->flush(seekPosition*1000); seekPosition = -1; } buffer=NULL; bufferSize=0; if(sampleID > numSamples){ mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } rc = MP4ReadSample(mp4file, mp4track, sampleID++, &buffer, &bufferSize, NULL, NULL, NULL, NULL); //g_print("%d/%d\n", sampleID-1, numSamples); if((rc==0) || (buffer== NULL)){ g_print("MP4: read error\n"); sampleBuffer = NULL; sampleID=0; mp4_ip.output->buffer_free(); mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ sampleBuffer = faacDecDecode(decoder, &frameInfo, buffer, bufferSize); if(frameInfo.error > 0){ g_print("MP4: %s\n", faacDecGetErrorMessage(frameInfo.error)); mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if(buffer){ g_free(buffer); buffer=NULL; bufferSize=0; } while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) xmms_usleep(30000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_NE, channels, frameInfo.samples<<1, sampleBuffer); mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1); } while(bPlaying && mp4_ip.output->buffer_free()){ xmms_usleep(10000); } mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } } else{ // WE ARE READING AN AAC FILE FILE *file = NULL; faacDecHandle decoder = 0; guchar *buffer = 0; gulong bufferconsumed = 0; gulong samplerate = 0; guchar channels; gulong buffervalid = 0; TitleInput* input; gchar *temp = g_strdup(args); gchar *ext = strrchr(temp, '.'); gchar *xmmstitle = NULL; faacDecConfigurationPtr config; if((file = fopen(args, "rb")) == 0){ g_print("AAC: can't find file %s\n", args); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((decoder = faacDecOpen()) == NULL){ g_print("AAC: Open Decoder Error\n"); fclose(file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } config = faacDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 0; faacDecSetConfiguration(decoder, config); if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ g_print("AAC: error g_malloc\n"); fclose(file); bPlaying = FALSE; faacDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ g_print("AAC: Error reading file\n"); g_free(buffer); fclose(file); bPlaying = FALSE; faacDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } XMMS_NEW_TITLEINPUT(input); input->file_name = g_basename(temp); input->file_ext = ext ? ext+1 : NULL; input->file_path = temp; if(!strncmp(buffer, "ID3", 3)){ gint size = 0; fseek(file, 0, SEEK_SET); size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; size+=10; fread(buffer, 1, size, file); buffervalid = fread(buffer, 1, BUFFER_SIZE, file); } xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); if(xmmstitle == NULL) xmmstitle = g_strdup(input->file_name); if(temp) g_free(temp); if(input->performer) g_free(input->performer); if(input->album_name) g_free(input->album_name); if(input->track_name) g_free(input->track_name); if(input->genre) g_free(input->genre); g_free(input); bufferconsumed = faacDecInit(decoder, buffer, buffervalid, &samplerate, &channels); if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ g_print("AAC: Output Error\n"); g_free(buffer); buffer=0; faacDecClose(decoder); fclose(file); mp4_ip.output->close_audio(); /* if(positionTable){ g_free(positionTable); positionTable=0; } */ g_free(xmmstitle); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } //if(bSeek){ //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); //}else{ mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); //} mp4_ip.output->flush(0); while(bPlaying && buffervalid > 0){ faacDecFrameInfo finfo; unsigned long samplesdecoded; char* sample_buffer = NULL; /* if(bSeek && seekPosition!=-1){ fseek(file, positionTable[seekPosition], SEEK_SET); bufferconsumed=0; buffervalid = fread(buffer, 1, BUFFER_SIZE, file); aac_ip.output->flush(seekPosition*1000); seekPosition=-1; } */ if(bufferconsumed > 0){ memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); buffervalid -= bufferconsumed; buffervalid += fread(&buffer[buffervalid], 1, BUFFER_SIZE-buffervalid, file); bufferconsumed = 0; } sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); if(finfo.error){ config = faacDecGetCurrentConfiguration(decoder); if(config->useOldADTSFormat != 1){ faacDecClose(decoder); decoder = faacDecOpen(); config = faacDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 1; faacDecSetConfiguration(decoder, config); finfo.bytesconsumed=0; finfo.samples = 0; faacDecInit(decoder, buffer, buffervalid, &samplerate, &channels); }else{ g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); buffervalid = 0; } } bufferconsumed += finfo.bytesconsumed; samplesdecoded = finfo.samples; if((samplesdecoded<=0) && !sample_buffer){ g_print("AAC: error sample decoding\n"); continue; } while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ xmms_usleep(10000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_LE, channels, samplesdecoded<<1, sample_buffer); mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); } while(bPlaying && mp4_ip.output->buffer_playing()){ xmms_usleep(10000); } mp4_ip.output->buffer_free(); mp4_ip.output->close_audio(); bPlaying = FALSE; g_free(buffer); faacDecClose(decoder); g_free(xmmstitle); fclose(file); seekPosition = -1; /* if(positionTable){ g_free(positionTable); positionTable=0; } */ bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } }
static void *dae_play_loop(void *arg) { char *buffer = g_malloc(CD_FRAMESIZE_RAW * CDDA_DAE_FRAMES); int pos = LBA(cdda_playing.cd_toc.track[cdda_playing.track]); int end, frames; if (cdda_playing.track == cdda_playing.cd_toc.last_track) end = LBA(cdda_playing.cd_toc.leadout); else end = LBA(cdda_playing.cd_toc.track[cdda_playing.track + 1]); while (cdda_playing.playing) { int left; char *data; if (dae_data.seek != -1) { cdda_ip.output->flush(dae_data.seek * 1000); pos = LBA(cdda_playing.cd_toc.track[cdda_playing.track]) + dae_data.seek * 75; dae_data.seek = -1; dae_data.eof = FALSE; } frames = MIN(CDDA_DAE_FRAMES, end - pos); if (frames == 0) dae_data.eof = TRUE; if (dae_data.eof) { xmms_usleep(30000); continue; } frames = read_audio_data(cdda_playing.fd, pos, frames, buffer); if (frames <= 0) { int err = -frames; if (err == EOPNOTSUPP) dae_data.eof = TRUE; else { /* * If the read failed, skip ahead to * avoid getting stuck on scratches * and such. */ g_message("read_audio_data() failed: %s (%d)", strerror(err), err); pos += MIN(CDDA_DAE_FRAMES, end - pos); } continue; } left = frames * CD_FRAMESIZE_RAW; data = buffer; while (cdda_playing.playing && left > 0 && dae_data.seek == -1) { int cur = MIN(512 * 2 * 2, left); cdda_ip.add_vis_pcm(cdda_ip.output->written_time(), FMT_S16_LE, 2, cur, data); while (cdda_ip.output->buffer_free() < cur && cdda_playing.playing && dae_data.seek == -1) xmms_usleep(30000); if (cdda_playing.playing && dae_data.seek == -1) cdda_ip.output->write_audio(data, cur); left -= cur; data += cur; } pos += frames; } cdda_ip.output->buffer_free(); cdda_ip.output->buffer_free(); g_free(buffer); return NULL; }
void *play_loop_(void *arg) { unsigned written_time_last = 0, bh_index_last_w = 0, bh_index_last_o = BITRATE_HIST_SIZE, blocksize = 1; FLAC__uint64 decode_position_last = 0, decode_position_frame_last = 0, decode_position_frame = 0; (void)arg; while(stream_data_.is_playing) { if(!stream_data_.eof) { while(sample_buffer_last_ - sample_buffer_first_ < SAMPLES_PER_WRITE) { unsigned s; s = sample_buffer_last_ - sample_buffer_first_; if(FLAC__stream_decoder_get_state(decoder_) == FLAC__STREAM_DECODER_END_OF_STREAM) { stream_data_.eof = true; break; } else if(!FLAC__stream_decoder_process_single(decoder_)) { /*@@@ this should probably be a dialog */ fprintf(stderr, "libxmms-flac: READ ERROR processing frame\n"); stream_data_.eof = true; break; } blocksize = sample_buffer_last_ - sample_buffer_first_ - s; decode_position_frame_last = decode_position_frame; if(stream_data_.is_http_source || !FLAC__stream_decoder_get_decode_position(decoder_, &decode_position_frame)) decode_position_frame = 0; } if(sample_buffer_last_ - sample_buffer_first_ > 0) { const unsigned n = min(sample_buffer_last_ - sample_buffer_first_, SAMPLES_PER_WRITE); int bytes = n * stream_data_.channels * stream_data_.sample_format_bytes_per_sample; FLAC__byte *sample_buffer_start = sample_buffer_ + sample_buffer_first_ * stream_data_.channels * stream_data_.sample_format_bytes_per_sample; unsigned written_time, bh_index_w; FLAC__uint64 decode_position; sample_buffer_first_ += n; flac_ip.add_vis_pcm(flac_ip.output->written_time(), stream_data_.sample_format, stream_data_.channels, bytes, sample_buffer_start); while(flac_ip.output->buffer_free() < (int)bytes && stream_data_.is_playing && stream_data_.seek_to_in_sec == -1) xmms_usleep(10000); if(stream_data_.is_playing && stream_data_.seek_to_in_sec == -1) flac_ip.output->write_audio(sample_buffer_start, bytes); /* compute current bitrate */ written_time = flac_ip.output->written_time(); bh_index_w = written_time / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; if(bh_index_w != bh_index_last_w) { bh_index_last_w = bh_index_w; decode_position = decode_position_frame - (double)(sample_buffer_last_ - sample_buffer_first_) * (double)(decode_position_frame - decode_position_frame_last) / (double)blocksize; bitrate_history_[(bh_index_w + BITRATE_HIST_SIZE - 1) % BITRATE_HIST_SIZE] = decode_position > decode_position_last && written_time > written_time_last ? 8000 * (decode_position - decode_position_last) / (written_time - written_time_last) : stream_data_.sample_rate * stream_data_.channels * stream_data_.bits_per_sample; decode_position_last = decode_position; written_time_last = written_time; } } else { stream_data_.eof = true; xmms_usleep(10000); } } else xmms_usleep(10000); if(!stream_data_.is_http_source && stream_data_.seek_to_in_sec != -1) { const double distance = (double)stream_data_.seek_to_in_sec * 1000.0 / (double)stream_data_.length_in_msec; FLAC__uint64 target_sample = (FLAC__uint64)(distance * (double)stream_data_.total_samples); if(stream_data_.total_samples > 0 && target_sample >= stream_data_.total_samples) target_sample = stream_data_.total_samples - 1; if(FLAC__stream_decoder_seek_absolute(decoder_, target_sample)) { flac_ip.output->flush(stream_data_.seek_to_in_sec * 1000); bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; if(!FLAC__stream_decoder_get_decode_position(decoder_, &decode_position_frame)) decode_position_frame = 0; stream_data_.eof = false; sample_buffer_first_ = sample_buffer_last_ = 0; } else if(FLAC__stream_decoder_get_state(decoder_) == FLAC__STREAM_DECODER_SEEK_ERROR) { /*@@@ this should probably be a dialog */ fprintf(stderr, "libxmms-flac: SEEK ERROR\n"); FLAC__stream_decoder_flush(decoder_); stream_data_.eof = false; sample_buffer_first_ = sample_buffer_last_ = 0; } stream_data_.seek_to_in_sec = -1; } else { /* display the right bitrate from history */ unsigned bh_index_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; if(bh_index_o != bh_index_last_o && bh_index_o != bh_index_last_w && bh_index_o != (bh_index_last_w + 1) % BITRATE_HIST_SIZE) { bh_index_last_o = bh_index_o; flac_ip.set_info(stream_data_.title, stream_data_.length_in_msec, bitrate_history_[bh_index_o], stream_data_.sample_rate, stream_data_.channels); } } } safe_decoder_finish_(decoder_); /* are these two calls necessary? */ flac_ip.output->buffer_free(); flac_ip.output->buffer_free(); g_free(stream_data_.title); pthread_exit(NULL); return 0; /* to silence the compiler warning about not returning a value */ }
static void *play_loop(void *arg) { enum uade_control_state controlstate = UADE_S_STATE; int ret; int left = 0; uint8_t space[UADE_MAX_MESSAGE_SIZE]; struct uade_msg *um = (struct uade_msg *) space; int subsong_end = 0; uint16_t *sm; int i; unsigned int play_bytes, tailbytes = 0; uint64_t subsong_bytes = 0; char *reason; uint32_t *u32ptr; int writeoffs; int framesize = UADE_CHANNELS * UADE_BYTES_PER_SAMPLE; int song_end_trigger = 0; int64_t skip_bytes = 0; uade_lock(); record_playtime = 1; uade_unlock(); while (1) { if (controlstate == UADE_S_STATE) { assert(left == 0); if (abort_playing) { uade_lock(); record_playtime = 0; uade_unlock(); break; } uade_lock(); if (uade_seek_forward) { skip_bytes += uade_seek_forward * UADE_BYTES_PER_FRAME * state.config.frequency; uade_ip.output->flush(uade_ip.output->written_time() + uade_seek_forward * 1000); uade_seek_forward = 0; } if (uade_select_sub != -1) { state.song->cur_subsong = uade_select_sub; uade_change_subsong(&state); uade_ip.output->flush(0); uade_select_sub = -1; subsong_end = 0; subsong_bytes = 0; /* we do this to avoid timeout, and to not record playtime */ state.song->out_bytes = 0; record_playtime = 0; uade_info_string(); } if (subsong_end && song_end_trigger == 0) { if (state.song->cur_subsong == -1 || state.song->max_subsong == -1) { song_end_trigger = 1; } else { state.song->cur_subsong++; if (state.song->cur_subsong > state.song->max_subsong) { song_end_trigger = 1; } else { int x = 0; uade_change_subsong(&state); while (uade_ip.output->buffer_playing()) { /* Sleep at most 5 secs */ if (x >= 500) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "UADE: blocking work-around activated.\n"); break; } x++; xmms_usleep(10000); } uade_ip.output->flush(0); subsong_end = 0; subsong_bytes = 0; uade_gui_subsong_changed(state.song->cur_subsong); uade_info_string(); } } } uade_unlock(); if (song_end_trigger) { /* We must drain the audio fast if abort_playing happens (e.g. the user changes song when we are here waiting the sound device) */ while (uade_ip.output->buffer_playing() && abort_playing == 0) xmms_usleep(10000); break; } left = uade_read_request(&state.ipc); if (uade_send_short_message(UADE_COMMAND_TOKEN, &state.ipc)) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Can not send token.\n"); return NULL; } controlstate = UADE_R_STATE; } else { if (uade_receive_message(um, sizeof(space), &state.ipc) <= 0) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Can not receive events from uade\n"); exit(1); } switch (um->msgtype) { case UADE_COMMAND_TOKEN: controlstate = UADE_S_STATE; break; case UADE_REPLY_DATA: sm = (uint16_t *) um->data; for (i = 0; i < um->size; i += 2) { *sm = ntohs(*sm); sm++; } if (subsong_end) { play_bytes = tailbytes; tailbytes = 0; } else { play_bytes = um->size; } if (subsong_end == 0 && song_end_trigger == 0 && uade_test_silence(um->data, play_bytes, &state)) { subsong_end = 1; } subsong_bytes += play_bytes; uade_lock(); state.song->out_bytes += play_bytes; uade_unlock(); if (skip_bytes > 0) { if (play_bytes <= skip_bytes) { skip_bytes -= play_bytes; play_bytes = 0; } else { play_bytes -= skip_bytes; skip_bytes = 0; } } uade_effect_run(&state.effects, (int16_t *) um->data, play_bytes / framesize); uade_ip.add_vis_pcm(uade_ip.output->written_time(), sample_format, UADE_CHANNELS, play_bytes, um->data); writeoffs = 0; while (writeoffs < play_bytes) { int writable; while ((writable = uade_ip.output->buffer_free()) <= 0) { if (abort_playing) goto nowrite; xmms_usleep(10000); } if (writable > (play_bytes - writeoffs)) writable = play_bytes - writeoffs; uade_ip.output->write_audio(&um->data[writeoffs], writable); writeoffs += writable; } nowrite: if (state.config.timeout != -1 && state.config.use_timeouts) { if (song_end_trigger == 0) { uade_lock(); if (state.song->out_bytes / (UADE_BYTES_PER_FRAME * state.config.frequency) >= state.config.timeout) { song_end_trigger = 1; record_playtime = 0; } uade_unlock(); } } if (state.config.subsong_timeout != -1 && state.config.use_timeouts) { if (subsong_end == 0 && song_end_trigger == 0) { if (subsong_bytes / (UADE_BYTES_PER_FRAME * state.config.frequency) >= state.config.subsong_timeout) { subsong_end = 1; record_playtime = 0; } } } assert (left >= um->size); left -= um->size; break; case UADE_REPLY_FORMATNAME: uade_check_fix_string(um, 128); strlcpy(gui_formatname, (char *) um->data, sizeof gui_formatname); strlcpy(state.song->formatname, (char *) um->data, sizeof state.song->formatname); break; case UADE_REPLY_MODULENAME: uade_check_fix_string(um, 128); strlcpy(gui_modulename, (char *) um->data, sizeof gui_modulename); strlcpy(state.song->modulename, (char *) um->data, sizeof state.song->modulename); break; case UADE_REPLY_MSG: uade_check_fix_string(um, 128); plugindebug("Message: %s\n", (char *) um->data); break; case UADE_REPLY_PLAYERNAME: uade_check_fix_string(um, 128); strlcpy(gui_playername, (char *) um->data, sizeof gui_playername); strlcpy(state.song->playername, (char *) um->data, sizeof state.song->playername); break; case UADE_REPLY_SONG_END: if (um->size < 9) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Invalid song end reply\n"); exit(1); } tailbytes = ntohl(((uint32_t *) um->data)[0]); /* next ntohl() is only there for a principle. it is not useful */ if (ntohl(((uint32_t *) um->data)[1]) == 0) { /* normal happy song end. go to next subsong if any */ subsong_end = 1; } else { /* unhappy song end (error in the 68k side). skip to next song ignoring possible subsongs */ song_end_trigger = 1; } i = 0; reason = (char *) &um->data[8]; while (reason[i] && i < (um->size - 8)) i++; if (reason[i] != 0 || (i != (um->size - 9))) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Broken reason string with song end notice\n"); exit(1); } break; case UADE_REPLY_SUBSONG_INFO: if (um->size != 12) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "subsong info: too short a message\n"); exit(1); } u32ptr = (uint32_t *) um->data; uade_lock(); state.song->min_subsong = ntohl(u32ptr[0]); state.song->max_subsong = ntohl(u32ptr[1]); state.song->cur_subsong = ntohl(u32ptr[2]); if (!(-1 <= state.song->min_subsong && state.song->min_subsong <= state.song->cur_subsong && state.song->cur_subsong <= state.song->max_subsong)) { int tempmin = state.song->min_subsong, tempmax = state.song->max_subsong; __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "uade: The player is broken. Subsong info does not match with %s.\n", gui_filename); state.song->min_subsong = tempmin <= tempmax ? tempmin : tempmax; state.song->max_subsong = tempmax >= tempmin ? tempmax : tempmin; if (state.song->cur_subsong > state.song->max_subsong) state.song->max_subsong = state.song->cur_subsong; else if (state.song->cur_subsong < state.song->min_subsong) state.song->min_subsong = state.song->cur_subsong; } uade_unlock(); break; default: __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Expected sound data. got %d.\n", um->msgtype); plugin_disabled = 1; return NULL; } } } last_beat_played = 1; if (uade_send_short_message(UADE_COMMAND_REBOOT, &state.ipc)) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Can not send reboot.\n"); return NULL; } if (uade_send_short_message(UADE_COMMAND_TOKEN, &state.ipc)) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Can not send token.\n"); return NULL; } do { ret = uade_receive_message(um, sizeof(space), &state.ipc); if (ret < 0) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Can not receive events from uade.\n"); return NULL; } if (ret == 0) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "End of input after reboot.\n"); return NULL; } } while (um->msgtype != UADE_COMMAND_TOKEN); return NULL; }