bool Mp3PspStream::seek(const Timestamp &where) { DEBUG_ENTER_FUNC(); if (where == _length) { _state = MP3_STATE_EOS; return true; } else if (where > _length) { return false; } const uint32 time = where.msecs(); mad_timer_t destination; mad_timer_set(&destination, time / 1000, time % 1000, 1000); // Important to release and re-init the ME releaseStreamME(); initStreamME(); // Check if we need to rewind if (_state != MP3_STATE_READY || mad_timer_compare(destination, _totalTime) < 0) { initStream(); } // Skip ahead while (mad_timer_compare(destination, _totalTime) > 0 && _state != MP3_STATE_EOS) findValidHeader(); return (_state != MP3_STATE_EOS); }
bool MP3Stream::rewind() { mad_timer_t destination; mad_timer_set(&destination, 0, 0, 1000); if (_state != MP3_STATE_READY || mad_timer_compare(destination, _totalTime) < 0) initStream(); while (mad_timer_compare(destination, _totalTime) > 0 && _state != MP3_STATE_EOS) readHeader(); return (_state != MP3_STATE_EOS); }
bool MP3Stream::seek(const Timestamp &where) { if (where == _length) { _state = MP3_STATE_EOS; return true; } else if (where > _length) { return false; } const uint32 time = where.msecs(); mad_timer_t destination; mad_timer_set(&destination, time / 1000, time % 1000, 1000); if (_state != MP3_STATE_READY || mad_timer_compare(destination, _totalTime) < 0) initStream(); while (mad_timer_compare(destination, _totalTime) > 0 && _state != MP3_STATE_EOS) readHeader(); decodeMP3Data(); return (_state != MP3_STATE_EOS); }
/* Do a seek based on the bitrate. */ int RageSoundReader_MP3::SetPosition_estimate( int iFrame ) { /* This doesn't leave us accurate. */ mad->timer_accurate = 0; mad_timer_t seekamt; mad_timer_set( &seekamt, 0, iFrame, mad->Frame.header.samplerate ); { /* We're going to skip ahead two samples below, so seek earlier than * we were asked to. */ mad_timer_t back_len = mad->framelength; mad_timer_multiply(&back_len, -2); mad_timer_add(&seekamt, back_len); if( mad_timer_compare(seekamt, mad_timer_zero) < 0 ) seekamt = mad_timer_zero; } int seekpos = mad_timer_count( seekamt, MAD_UNITS_MILLISECONDS ) * (mad->bitrate / 8 / 1000); seekpos += mad->header_bytes; seek_stream_to_byte( seekpos ); /* We've jumped across the file, so the decoder is currently desynced. * Don't use resync(); it's slow. Just decode a few frames. */ for( int i = 0; i < 2; ++i ) { int ret = do_mad_frame_decode(); if( ret <= 0 ) return ret; } /* Throw out one synth. */ synth_output(); mad->outleft = 0; /* Find out where we really seeked to. */ int ms = (get_this_frame_byte(mad) - mad->header_bytes) / (mad->bitrate / 8 / 1000); mad_timer_set(&mad->Timer, 0, ms, 1000); return 1; }
enum mad_flow read_header(void *data, struct mad_header const * header) { char long_currenttime_str[14]; /* this *will* fill if you're using 100000+ minute mp3s */ char long_remaintime_str[14]; static int frames_played = 0; buffer *playbuf = (buffer *)data; mad_timer_t time_remaining; char *ao_time; if (stop_playing_file) { stop_playing_file = 0; status = MPG321_STOPPED; return MAD_FLOW_STOP; } if(options.opt & MPG321_REMOTE_PLAY) { enum mad_flow mf; /* We might have to stop if the user inputs something */ if ((mf = remote_get_input_nowait(playbuf))) return mf; } /* Stop playing if -n is used, and we're at the frame specified. */ if ((playbuf->max_frames != -1) && (frames_played++ > playbuf->max_frames)) { frames_played = 0; status = MPG321_STOPPED; if(options.opt & MPG321_ENABLE_BUFFER) Decoded_Frames->done = 1; //fprintf(stderr,"Total D: %d\n",Decoded_Frames->total_decoded_frames); return MAD_FLOW_STOP; } current_frame++; mad_timer_add(¤t_time, header->duration); if(options.opt & MPG321_USE_SCROBBLER && scrobbler_time > 0 && scrobbler_time < current_time.seconds) { scrobbler_time = -1; scrobbler_report(); } if(options.opt & (MPG321_VERBOSE_PLAY | MPG321_REMOTE_PLAY)) { mad_timer_string(current_time, long_currenttime_str, "%.2u:%.2u.%.2u", MAD_UNITS_MINUTES, MAD_UNITS_CENTISECONDS, 0); if (mad_timer_compare(playbuf->duration, mad_timer_zero) == 0) time_remaining = current_time; else time_remaining = playbuf->duration; mad_timer_negate(¤t_time); mad_timer_add(&time_remaining, current_time); mad_timer_negate(¤t_time); mad_timer_string(time_remaining, long_remaintime_str, "%.2u:%.2u.%.2u", MAD_UNITS_MINUTES, MAD_UNITS_CENTISECONDS, 0); } /* update cached table of frames & times */ if (current_frame <= playbuf->num_frames) /* we only allocate enough for our estimate. */ { playbuf->frames[current_frame] = playbuf->frames[current_frame-1] + (header->bitrate / 8 / 1000) * mad_timer_count(header->duration, MAD_UNITS_MILLISECONDS); playbuf->times[current_frame] = current_time; } if (file_change) { file_change = 0; if (options.opt & MPG321_REMOTE_PLAY) { printf("@S %s %d %d %s %d %ld %d %d %d %d %ld %d\n",versionstring(header->flags), header->layer, header->samplerate, modestringucase(header->mode), header->mode_extension, (header->bitrate / 8 / 100) * mad_timer_count(header->duration, MAD_UNITS_CENTISECONDS), MAD_NCHANNELS(header), header->flags & MAD_FLAG_COPYRIGHT ? 1 : 0, header->flags & MAD_FLAG_PROTECTION ? 1 : 0, header->emphasis, header->bitrate/1000, header->mode_extension); } else if (options.opt & MPG321_VERBOSE_PLAY)/*zip it good*/ { fprintf(stderr, "MPEG %s, Layer: %s, Freq: %d, mode: %s, modext: %d, BPF : %ld\n" "Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n" "Bitrate: %ld Kbits/s, Extension value: %d\n" "Audio: 1:1 conversion, rate: %d, encoding: signed 16 bit, channels: %d\n", versionstring(header->flags),layerstring(header->layer), header->samplerate, modestringucase(header->mode), header->mode_extension, (header->bitrate / 100) * mad_timer_count(header->duration, MAD_UNITS_CENTISECONDS), MAD_NCHANNELS(header), header->flags & MAD_FLAG_COPYRIGHT ? "Yes" : "No", header->flags & MAD_FLAG_ORIGINAL ? "Yes" : "No", header->flags & MAD_FLAG_PROTECTION ? "Yes" : "No", header->emphasis, header->bitrate/1000, header->mode_extension, header->samplerate, MAD_NCHANNELS(header)); } else if (!(options.opt & MPG321_QUIET_PLAY))/*I love Joey*/ { fprintf(stderr, "MPEG %s layer %s, %ld kbit/s, %d Hz %s\n", versionstring(header->flags),layerstring(header->layer), header->bitrate/1000, header->samplerate, modestring(header->mode)); } } if (status == MPG321_SEEKING && options.seek) { if (!--options.seek) status = MPG321_PLAYING; return MAD_FLOW_IGNORE; } else { status = MPG321_PLAYING; } if(!(options.opt & MPG321_ENABLE_BUFFER)) { if(count > 0) { count++; if(count > 40) { if(!(options.opt & MPG321_VERBOSE_PLAY)) fprintf(stderr," \r"); count = -1; fflush(stderr); } } } if(options.opt & MPG321_ENABLE_BUFFER) { ao_time = (Output_Queue+mad_decoder_position)->time; (Output_Queue+mad_decoder_position)->num_frames = playbuf->num_frames - current_frame; if(Decoded_Frames->is_file) (Output_Queue+mad_decoder_position)->seconds = time_remaining.seconds; } if (options.opt & MPG321_VERBOSE_PLAY) { if (!options.skip_printing_frames || (options.skip_printing_frames && !(current_frame % options.skip_printing_frames))) if(count > 0) { /* if(options.opt & MPG321_ENABLE_BUFFER) { sprintf(ao_time, "Frame# %5lu [%5lu], Time: %s [%s], \r", current_frame, playbuf->num_frames > 0 ? playbuf->num_frames - current_frame : 0, long_currenttime_str, long_remaintime_str); //sprintf(ao_time, "Frame# %5lu [%5lu], Time: %s [%s], \r", current_frame, // playbuf->num_frames > 0 ? playbuf->num_frames - current_frame : 0, long_currenttime_str, long_remaintime_str); //sprintf(ao_time, "Volume: %d%% Frame# %5lu [%5lu], Time: %s [%s], \r",volume, current_frame, // playbuf->num_frames > 0 ? playbuf->num_frames - current_frame : 0, long_currenttime_str, long_remaintime_str); }else*/ { fprintf(stderr, "Volume: %d%% Frame# %5lu [%5lu], Time: %s [%s], \r",volume, current_frame, playbuf->num_frames > 0 ? playbuf->num_frames - current_frame : 0, long_currenttime_str, long_remaintime_str); } } else if(count < 0) { if(options.opt & MPG321_ENABLE_BUFFER) { // sprintf(ao_time, "Frame# %5lu [%5lu], Time: %s [%s], \r", current_frame, sprintf(ao_time, "Frame# %5lu [%5lu], Time: %s [%s], \r", current_frame, playbuf->num_frames > 0 ? playbuf->num_frames - current_frame : 0, long_currenttime_str, long_remaintime_str); } else { fprintf(stderr, "Frame# %5lu [%5lu], Time: %s [%s], \r", current_frame, playbuf->num_frames > 0 ? playbuf->num_frames - current_frame : 0, long_currenttime_str, long_remaintime_str); } } } else if (options.opt & MPG321_REMOTE_PLAY) { if (!options.skip_printing_frames || (options.skip_printing_frames && !(current_frame % options.skip_printing_frames))) { if(options.opt & MPG321_ENABLE_BUFFER) { sprintf(ao_time,"@F %ld %ld %.2f %.2f\n", current_frame, playbuf->num_frames - current_frame, ((double)mad_timer_count(current_time, MAD_UNITS_CENTISECONDS)/100.0), ((double)mad_timer_count(time_remaining, MAD_UNITS_CENTISECONDS)/100.0)); } else { fprintf(stderr,"@F %ld %ld %.2f %.2f\n", current_frame, playbuf->num_frames - current_frame, ((double)mad_timer_count(current_time, MAD_UNITS_CENTISECONDS)/100.0), ((double)mad_timer_count(time_remaining, MAD_UNITS_CENTISECONDS)/100.0)); } } } return MAD_FLOW_CONTINUE; }
int RageSoundReader_MP3::SetPosition_hard( int iFrame ) { mad_timer_t desired; mad_timer_set( &desired, 0, iFrame, mad->Frame.header.samplerate ); /* This seek doesn't change the accuracy of our timer. */ /* If we're already exactly at the requested position, OK. */ if( mad_timer_compare(mad->Timer, desired) == 0 ) return 1; /* We always come in here with data synthed. Be careful not to synth the * same frame twice. */ bool synthed=true; /* If we're already past the requested position, rewind. */ if(mad_timer_compare(mad->Timer, desired) > 0) { MADLIB_rewind(); do_mad_frame_decode(); synthed = false; } /* Decode frames until the current frame contains the desired offset. */ while(1) { /* If desired < next_frame_timer, this frame contains the position. Since we've * already decoded the frame, synth it, too. */ mad_timer_t next_frame_timer = mad->Timer; mad_timer_add( &next_frame_timer, mad->framelength ); if( mad_timer_compare(desired, next_frame_timer) < 0 ) { if( !synthed ) { synth_output(); } else { mad->outleft += mad->outpos; mad->outpos = 0; } /* We just synthed data starting at mad->Timer, containing the desired offset. * Skip (desired - mad->Timer) worth of frames in the output to line up. */ mad_timer_t skip = desired; mad_timer_sub( &skip, mad->Timer ); int samples = mad_timer_count( skip, (mad_units) SampleRate ); /* Skip 'samples' samples. */ mad->outpos = samples * this->Channels; mad->outleft -= samples * this->Channels; return 1; } /* Otherwise, if the desired time will be in the *next* decode, then synth * this one, too. */ mad_timer_t next_next_frame_timer = next_frame_timer; mad_timer_add( &next_next_frame_timer, mad->framelength ); if( mad_timer_compare(desired, next_next_frame_timer) < 0 && !synthed ) { synth_output(); synthed = true; } int ret = do_mad_frame_decode(); if( ret <= 0 ) { mad->outleft = mad->outpos = 0; return ret; /* it set the error */ } synthed = false; } }
bool operator() ( const mad_timer_t &timer1, const mad_timer_t &timer2 ) const { return mad_timer_compare( timer1, timer2 ) < 0; }
/* * NAME: fadein_filter() * DESCRIPTION: fade-in filter */ enum mad_flow fadein_filter(void *data, struct mad_frame *frame) { struct player *player = data; if (mad_timer_compare(player->stats.play_timer, player->fade_in) < 0) { mad_timer_t frame_start, frame_end, ratio; unsigned int nch, nsamples, s; mad_fixed_t step, scalefactor; /* * Fade-in processing may occur over the entire frame, or it may end * somewhere within the frame. Find out where processing should end. */ nsamples = MAD_NSBSAMPLES(&frame->header); /* this frame has not yet been added to play_timer */ frame_start = frame_end = player->stats.play_timer; mad_timer_add(&frame_end, frame->header.duration); if (mad_timer_compare(player->fade_in, frame_end) < 0) { mad_timer_t length; length = frame_start; mad_timer_negate(&length); mad_timer_add(&length, player->fade_in); mad_timer_set(&ratio, 0, mad_timer_count(length, frame->header.samplerate), mad_timer_count(frame->header.duration, frame->header.samplerate)); nsamples = mad_timer_fraction(ratio, nsamples); } /* determine starting scalefactor and step size */ mad_timer_set(&ratio, 0, mad_timer_count(frame_start, frame->header.samplerate), mad_timer_count(player->fade_in, frame->header.samplerate)); scalefactor = mad_timer_fraction(ratio, MAD_F_ONE); step = MAD_F_ONE / (mad_timer_count(player->fade_in, frame->header.samplerate) / 32); /* scale subband samples */ nch = MAD_NCHANNELS(&frame->header); for (s = 0; s < nsamples; ++s) { unsigned int ch, sb; for (ch = 0; ch < nch; ++ch) { for (sb = 0; sb < 32; ++sb) { frame->sbsample[ch][s][sb] = mad_f_mul(frame->sbsample[ch][s][sb], scalefactor); } } scalefactor += step; } } return MAD_FLOW_CONTINUE; }