Esempio n. 1
0
void alogg_seek_rel_secs_ogg(ALOGG_OGG *ogg, int sec) {
  double s = sec;
  s += ov_time_tell(&(ogg->vf));
  ov_time_seek(&(ogg->vf), s);
}
Esempio n. 2
0
const int oggDecoder::getTime( )
{
	return int(ov_time_tell( decoder ));
}
Esempio n. 3
0
/* process the Ogg from start_time to end_time, passing the decoded data to the supplied callback
   if the start and end time are the same value, the entire OGG is processed from the specified start time until the end of the file
   buffer_samples is the internally allocated buffer size to use */
int alogg_process_ogg(ALOGG_OGG * ogg, void(*callback)(void * buf, int nsamples, int stereo), int buffer_samples, double start_time, double end_time)
{
	int size_done, i, all_done = 0;
	int ret = 0;
	int bits;
	char * buffer;
	char * buffer_p;
	double current_pos;
	int buffer_bytes = buffer_samples * 2;
	unsigned long num_samples_left = 0, num_samples_decoded;
	char all = 0;	//Is set to nonzero if the OGG is to be processed until the end of the file

	buffer = malloc(buffer_bytes);
	if(!buffer)
	{
		return 0;
	}

	current_pos = ov_time_tell(&(ogg->vf));
	ov_time_seek(&(ogg->vf), start_time);

	if(start_time == end_time)
	{	//If the calling function intends to process the OGG until the end of the file
		all = 1;
	}
	else
	{
		num_samples_left = ((end_time - start_time) * alogg_get_wave_freq_ogg(ogg)) * (ogg->stereo ? 2 : 1);	//The number of samples to pass to the callback function
	}
	bits = alogg_get_wave_bits_ogg(ogg);	//The number of bits per sample (expected to be 16)
	if(bits != 16)
	{	//Unexpected sample size
		free(buffer);
		return 0;
	}

	while(!all_done)
	{
		buffer_p = buffer;
		for(i = 0; i < buffer_samples; i++)
		{	//Fill buffer with silent audio
			((unsigned short *)(buffer_p))[i] = 0x8000;
		}
		size_done = num_samples_decoded = 0;

		/* read samples from Ogg Vorbis file */
		for(i = buffer_bytes; i > 0; i -= size_done)
		{
			/* decode */
			size_done = ov_read(&(ogg->vf), buffer_p, i, alogg_endianess, 2, 0, &(ogg->current_section));

			/* check if the decoding was not successful */
			if(size_done < 0)
			{
				if(size_done == OV_HOLE)
				{
					size_done = 0;
				}
				else
				{
					all_done = 2;
				}
			}
			else if(size_done == 0)
			{	//No more samples
				all_done = 1;
				ret = 1;
				break; // playback finished so get out of loop
			}
			num_samples_decoded += size_done / 2;	//Keep track of how many samples have been decoded since the last callback
			buffer_p += size_done;
		}
		if(all || (num_samples_decoded < num_samples_left))
		{	//If all of the newly decoded samples are to be passed to the callback
		   callback(buffer, buffer_samples, ogg->stereo);
		   num_samples_left -= num_samples_decoded;
		}
		else
		{	//If the samples passed to the callback will be limited to the given time range
		   callback(buffer, num_samples_left, ogg->stereo);
		   all_done = 3;
		   ret = 1;
		}
	}
    free(buffer);
    ov_time_seek(&(ogg->vf), current_pos);
    return ret;
}
CBaseDec::RetCode COggDec::Decoder(FILE *in, const int OutputFd, State* const state, CAudioMetaData* meta_data, time_t* const time_played, unsigned int* const secondsToSkip)
{
  OggVorbis_File vf;
  int bitstream, rval;
  ogg_int64_t jumptime=0;
  Status=OK;
  mOutputFd = OutputFd;
  mState = state;
  mTimePlayed=time_played;

  if (!Open(in, &vf))
  {
	  Status=DATA_ERR;
	  return Status;
  }

  SetMetaData(&vf, meta_data);

  audioDecoder->PrepareClipPlay(ov_info(&vf,0)->channels, ov_info(&vf,0)->rate, 16, 1);

  /* up and away ... */
  mSlotSize = MAX_OUTPUT_SAMPLES * 2 * ov_info(&vf,0)->channels;
  for(int i = 0 ; i < DECODE_SLOTS ; i++)
  {
	  if ((mPcmSlots[i] = (char*) malloc(mSlotSize)) == NULL)
	  {
		  for (int j = i - 1; j >= 0; j--)
		  {
			  free(mPcmSlots[j]);
		  }
		  Status=INTERNAL_ERR;
		  return Status;
	  }
	  mSlotTime[i]=0;
  }
  mReadSlot=mWriteSlot=0;

  pthread_t OutputThread;
  if (pthread_create (&OutputThread, 0, OutputDsp, (void *) this) != 0 )
  {
	  for(int i = 0 ; i < DECODE_SLOTS ; i++)
		  free(mPcmSlots[i]);
	  Status=INTERNAL_ERR;
	  return Status;
  }

  int bytes;
  State oldstate=*state;
  do
  {
	  // clear buffer on state change
	  if(oldstate!=*state)
	  {
		  if(*state!=PAUSE && (*state!=PLAY || oldstate!=PAUSE))
		  {
			  mWriteSlot=mReadSlot=0;
			  oldstate=*state;
		  }
	  }
	  while((mWriteSlot+1)%DECODE_SLOTS == mReadSlot)
	  {
		  usleep(10000);
	  }
	  bytes=0;
	  if(mSeekable)
#ifdef DBOX
		  mSlotTime[mWriteSlot] = ov_time_tell(&vf);
#else
		  mSlotTime[mWriteSlot] = (ogg_int64_t)(1000 * ov_time_tell(&vf));
#endif
	  do
	  {
#ifdef DBOX
		  rval = ov_read(&vf, mPcmSlots[mWriteSlot]+bytes, mSlotSize-bytes, &bitstream);
#else
		  rval = ov_read(&vf, mPcmSlots[mWriteSlot]+bytes, mSlotSize-bytes, 0, 2, 1, &bitstream);
#endif
		  bytes+=rval;
//printf("Ogg: read buf 0x%x size %d / %d done %d\n", mPcmSlots[mWriteSlot]+bytes, rval, mSlotSize, bytes);
	  } while (rval > 0 && bytes !=mSlotSize);
//printf("\n");
	  int actMSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip * 1000 : MSECS_TO_SKIP;
	  if((*state==FF || *state==REV) && mSeekable )
	  {
		  if((std::abs((long int)( mSlotTime[mWriteSlot]-jumptime))) > MSECS_TO_PLAY)
		  {
			  if(*state==FF)
			  {
				  ov_time_seek_page(&vf, mSlotTime[mWriteSlot] + actMSecsToSkip);
				  jumptime=mSlotTime[mWriteSlot]+actMSecsToSkip;
			  }
			  else
			  {
				  if(mSlotTime[mWriteSlot] < actMSecsToSkip)
				  {
					  ov_time_seek(&vf, 0);
					  *state=PLAY;
				  }
				  else
				  {
					  ov_time_seek_page(&vf, mSlotTime[mWriteSlot] - actMSecsToSkip);
					  jumptime=mSlotTime[mWriteSlot]-actMSecsToSkip;
				  }
			  }
		  }
		  if (*secondsToSkip != 0) {
			  *state=PLAY;
		  }
	  }
	  if(bytes == mSlotSize)
		  mWriteSlot=(mWriteSlot+1) % DECODE_SLOTS;
  } while (rval != 0 && *state!=STOP_REQ && Status==OK);

  //printf("COggDec::Decoder: read loop stop, rval %d state %d status %d\n", rval, *state, Status);
  // let buffer run dry
  while(rval==0 && *state!=STOP_REQ && Status==OK && mReadSlot != mWriteSlot)
	  usleep(100000);

  //pthread_cancel(OutputThread);
  //printf("COggDec::Decoder: OutputThread join\n");
  Status = WRITE_ERR;
  pthread_join(OutputThread, NULL);
  //printf("COggDec::Decoder: OutputThread join done\n");
  audioDecoder->StopClip();
  for(int i = 0 ; i < DECODE_SLOTS ; i++)
	  free(mPcmSlots[i]);

  /* clean up the junk from the party */
  ov_clear(&vf);

  /* and drive home ;) */
  return Status;
}
Esempio n. 5
0
int vorbis_get_current_pos() {
	return ov_time_tell(&track);
}
Esempio n. 6
0
int alogg_get_pos_secs_ogg(ALOGG_OGG *ogg) {
  return (int)ov_time_tell(&(ogg->vf));
}
Esempio n. 7
0
bool ImportOGG(wxWindow * parent,
               wxString Filename, WaveTrack ** channels[],
               int *numChannels, DirManager * dirManager)
{

   wxFFile file(Filename, "rb");

   if (!file.IsOpened()) {
      // No need for a message box, it's done automatically (but how?)
      return false;
   }

   OggVorbis_File vf;
   int err = ov_open(file.fp(), &vf, NULL, 0);

   if (err < 0) {
      wxString message;

      switch (err) {
         case OV_EREAD:
            message = _("Media read error");
            break;
         case OV_ENOTVORBIS:
            message = _("Not an Ogg Vorbis file");
            break;
         case OV_EVERSION:
            message = _("Vorbis version mismatch");
            break;
         case OV_EBADHEADER:
            message = _("Invalid Vorbis bitstream header");
            break;
         case OV_EFAULT:
            message = _("Internal logic fault");
            break;
      }

      wxMessageBox(message);
      file.Close();
      return false;
   }

   /* -1 is for the current logical bitstream */
   vorbis_info *vi = ov_info(&vf, -1);

   *numChannels = vi->channels;
   *channels = new WaveTrack *[*numChannels];

   int c;
   for (c = 0; c < *numChannels; c++) {
      (*channels)[c] = new WaveTrack(dirManager);
      (*channels)[c]->SetRate(vi->rate);
      (*channels)[c]->SetSampleFormat(int16Sample);

      switch (c) {
         case 0:
            (*channels)[c]->SetChannel(VTrack::LeftChannel);
            break;
         case 1:
            (*channels)[c]->SetChannel(VTrack::RightChannel);
            break;
         default:
            (*channels)[c]->SetChannel(VTrack::MonoChannel);
      }
   }

   if (*numChannels == 2)
      (*channels)[0]->SetLinked(true);

   wxProgressDialog *progress = NULL;

   wxYield();
   wxStartTimer();

/* The number of bytes to get from the codec in each run */
#define CODEC_TRANSFER_SIZE 4096
   
   const int bufferSize = 1048576;
   short *mainBuffer = new short[CODEC_TRANSFER_SIZE];

   short **buffers = new short *[*numChannels];
   for (int i = 0; i < *numChannels; i++) {
      buffers[i] = new short[bufferSize];
   }

   /* determine endianness (clever trick courtesy of Nicholas Devillard,
    * (http://www.eso.org/~ndevilla/endian/) */
   int testvar = 1, endian;
   if(*(char *)&testvar)
      endian = 0;  // little endian
   else
      endian = 1;  // big endian

   /* number of samples currently in each channel's buffer */
   int bufferCount = 0;
   bool cancelled = false;
   long bytesRead = 0;
   long samplesRead = 0;
   int bitstream = 0;

   do {
      bytesRead = ov_read(&vf, (char *) mainBuffer, CODEC_TRANSFER_SIZE,
                          endian,
                          2,    // word length (2 for 16 bit samples)
                          1,    // signed
                          &bitstream);
      samplesRead = bytesRead / *numChannels / sizeof(short);

      if (samplesRead + bufferCount > bufferSize) {
         for (c = 0; c < *numChannels; c++)
            (*channels)[c]->Append((samplePtr)buffers[c],
                                   int16Sample,
                                   bufferCount);
         bufferCount = 0;
      }

      /* Un-interleave */
      for (int s = 0; s < samplesRead; s++)
         for (c = 0; c < *numChannels; c++)
            buffers[c][s + bufferCount] =
                mainBuffer[s * (*numChannels) + c];

      bufferCount += samplesRead;


      if (!progress && wxGetElapsedTime(false) > 500)
         progress = new wxProgressDialog(_("Import"),
                                         _("Importing Ogg Vorbis File..."),
                                         1000,
                                         parent,
                                         wxPD_CAN_ABORT |
                                         wxPD_REMAINING_TIME |
                                         wxPD_AUTO_HIDE);

      if (progress)
         cancelled = !progress->Update(ov_time_tell(&vf) * 1000 /
                                       ov_time_total(&vf, bitstream));

   } while (!cancelled && bytesRead != 0 && bitstream == 0);

   /* ...the rest is de-allocation */
   ov_clear(&vf);
   file.Detach();    // so that it doesn't try to close the file (ov_clear()
                     // did that already)

   delete[]mainBuffer;

   for (c = 0; c < *numChannels; c++)
      delete[]buffers[c];
   delete[]buffers;

   if (progress)
      delete progress;

   if (cancelled) {
      for (c = 0; c < *numChannels; c++)
         delete(*channels)[c];
      delete[] * channels;

      return false;
   }

   return true;

}
Esempio n. 8
0
static void ogg_play_task(mp_callback_func cb)
{
	long							ret = 0;
	int							current_section = 0;
	double						time_seek_to = 0;
	vorbis_info					*vi;
	struct snd_device				*sound_dev;
	int							*processed_pcm;
	double						song_time;
	
	PE_DBG_PRINTF("MusicEngine: ==> ogg_play_task()! \n");

	sound_dev = (struct snd_device*)dev_get_by_type(NULL, HLD_DEV_TYPE_SND);
	processed_pcm = (int*)ogg_file->processed_pcm_buff;

	if (ov_open(ogg_file->file, &ogg_file->vf, NULL, 0) < 0)
	{
		PE_DBG_PRINTF("MusicEngine: ogg_play_task() ov_open failed! \n");
#ifdef ENABLE_PE_CACHE
		pe_cache_close(ogg_cache_id);                   // 这个ogg_cache_id是在play_file时打开
		ogg_cache_id = -1;
#else
		fclose(ogg_file->file);
#endif
		//FREE(processed_pcm);
		osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_UNSUCCESSFUL);
		return;
	}
	else
	{
		PE_DBG_PRINTF("MusicEngine: ov_opened \n");

		{

		vorbis_info *vi = ov_info(&ogg_file->vf, -1);
		if (!vi)
		{
			PE_DBG_PRINTF("MusicEngine: ov_info failed!\n");
			ov_clear(&ogg_file->vf);
			osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_UNSUCCESSFUL);
			return;
		}
		ogg_file->samplerate = vi->rate;
		ogg_file->channel = vi->channels;

		PE_DBG_PRINTF("\nBitstream is %d channel, %ldHz\n", vi->channels, vi->rate);
		song_time = ov_time_total(&ogg_file->vf, -1);
		if (song_time <= 0)
		{
			PE_DBG_PRINTF("MusicEngine: ov_info failed!\n");
			ov_clear(&ogg_file->vf);
			osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_UNSUCCESSFUL);
		}
		
		}

		osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_SUCCESS);
	}

	//all work success, we can start to play
	while (ogg_file->command  != OGG_CMD_STOP)
	{
		if (ogg_file->seek_to != 0)
		{
			time_seek_to = ov_time_tell(&ogg_file->vf);
			time_seek_to = time_seek_to + (ogg_file->seek_to * 1000);
	
			if (time_seek_to < 0)
			{
				time_seek_to = 0;
			}
			else if (time_seek_to > song_time)
			{
				time_seek_to = song_time;
			}

			ret = ov_time_seek(&ogg_file->vf, time_seek_to);
			if (ret < 0)
			{
				//seek failed
			}
			osal_task_dispatch_off();
			ogg_file->seek_to = 0;
			osal_task_dispatch_on();
		}

		if (ogg_file->command  == OGG_CMD_NONE)
		{
			ret = ov_read(&ogg_file->vf, (void *)ogg_file->pcm_out_buff, 2304, &current_section);
			if (ret == 0)
			{
				PE_DBG_PRINTF("file end!\n");
				//EOF we need call back
				
							
				osal_task_dispatch_off();
				if (ogg_file->command != OGG_CMD_STOP)
				{
					ogg_file->command  = OGG_CMD_WAIT_FOR_STOP;
				}
				osal_task_dispatch_on();
				
				cb(MP_MUSIC_PLAYBACK_END, 0);
							
				osal_task_sleep(10);
			}
			else if (ret < 0)
			{ 
				PE_DBG_PRINTF("error!!!\n");			
				/* error in the stream.  Not a problem, just reporting it in case we (the app) cares.  In this case, we don't. */

				osal_task_dispatch_off();
				if (ogg_file->command != OGG_CMD_STOP)
				{
					ogg_file->command  = OGG_CMD_WAIT_FOR_STOP;
				}
				osal_task_dispatch_on();
				
				cb(MP_MUSIC_PLAYBACK_END, 0);

				osal_task_sleep(10);
			}
			else
			{
				/* we don't bother dealing with sample rate changes, etc, but you'll have to*/
				process_ogg_pcm(sound_dev, ret, processed_pcm);
			}
		}
		else
		{
			osal_task_sleep(10);
		}

	}

	ov_clear(&ogg_file->vf);
	ogg_avoid_under_run = 0;
	snd_io_control(sound_dev, SND_CC_MUTE, 0);
	snd_stop(sound_dev);
	//FREE(processed_pcm);
	osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_TASK_EXIT);            // task结束,发出EXIT消息
	PE_DBG_PRINTF("MusicEngine: <== ogg_play_task()! \n");
	
}
Esempio n. 9
0
/*
 * Change position in the file.
 */
void
OGG_Seek ( ogg_seek_t type, double offset )
{
	double pos; /* Position in file (in seconds). */
	double total; /* Length of file (in seconds). */

	/* Check if the file is seekable. */
	if ( ov_seekable( &ovFile ) == 0 )
	{
		Com_Printf( "OGG_Seek: file is not seekable.\n" );
		return;
	}

	/* Get file information. */
	pos = ov_time_tell( &ovFile );
	total = ov_time_total( &ovFile, -1 );

	switch ( type )
	{
		case ABS:

			if ( ( offset >= 0 ) && ( offset <= total ) )
			{
				if ( ov_time_seek( &ovFile, offset ) != 0 )
				{
					Com_Printf( "OGG_Seek: could not seek.\n" );
				}

				else
				{
					Com_Printf( "%0.2f -> %0.2f of %0.2f.\n", pos, offset, total );
				}
			}
			else
			{
				Com_Printf( "OGG_Seek: invalid offset.\n" );
			}

			break;
		case REL:

			if ( ( pos + offset >= 0 ) && ( pos + offset <= total ) )
			{
				if ( ov_time_seek( &ovFile, pos + offset ) != 0 )
				{
					Com_Printf( "OGG_Seek: could not seek.\n" );
				}

				else
				{
					Com_Printf( "%0.2f -> %0.2f of %0.2f.\n", pos, pos + offset, total );
				}
			}
			else
			{
				Com_Printf( "OGG_Seek: invalid offset.\n" );
			}

			break;
	}
}
Esempio n. 10
0
	float cOggDecoder::getCurrentTime()
	{
		return ov_time_tell(&oggStream);
	}
Esempio n. 11
0
/* this is the codec entry point */
enum codec_status codec_main(void)
{
    ov_callbacks callbacks;
    OggVorbis_File vf;
    ogg_int32_t **pcm;

    int error;
    long n;
    int current_section;
    int previous_section;
    int eof;
    ogg_int64_t vf_offsets[2];
    ogg_int64_t vf_dataoffsets;
    ogg_uint32_t vf_serialnos;
    ogg_int64_t vf_pcmlengths[2];

    ci->configure(DSP_SET_SAMPLE_DEPTH, 24);

    if (codec_init()) {
        error = CODEC_ERROR;
        goto exit;
    }

    ogg_malloc_init();

#if defined(CPU_ARM) || defined(CPU_COLDFIRE) || defined(CPU_MIPS)
    if (setjmp(rb_jump_buf) != 0) {
        /* malloc failed; skip to next track */
        error = CODEC_ERROR;
        goto done;
    }
#endif

next_track:
    while (!*ci->taginfo_ready && !ci->stop_codec)
        ci->sleep(1);

    /* Create a decoder instance */
    callbacks.read_func = read_handler;
    callbacks.seek_func = initial_seek_handler;
    callbacks.tell_func = tell_handler;
    callbacks.close_func = close_handler;

    /* Open a non-seekable stream */
    error = ov_open_callbacks(ci, &vf, NULL, 0, callbacks);
    
    /* If the non-seekable open was successful, we need to supply the missing
     * data to make it seekable.  This is a hack, but it's reasonable since we
     * don't want to run the whole file through the buffer before we start
     * playing.  Using Tremor's seekable open routine would cause us to do
     * this, so we pretend not to be seekable at first.  Then we fill in the
     * missing fields of vf with 1) information in ci->id3, and 2) info
     * obtained by Tremor in the above ov_open call.
     *
     * Note that this assumes there is only ONE logical Vorbis bitstream in our
     * physical Ogg bitstream.  This is verified in metadata.c, well before we
     * get here.
     */
    if (!error) {
         ogg_free(vf.offsets);
         ogg_free(vf.dataoffsets);
         ogg_free(vf.serialnos);

         vf.offsets = vf_offsets;
         vf.dataoffsets = &vf_dataoffsets;
         vf.serialnos = &vf_serialnos;
         vf.pcmlengths = vf_pcmlengths;

         vf.offsets[0] = 0;
         vf.offsets[1] = ci->id3->filesize;
         vf.dataoffsets[0] = vf.offset;
         vf.pcmlengths[0] = 0;
         vf.pcmlengths[1] = ci->id3->samples;
         vf.serialnos[0] = vf.current_serialno;
         vf.callbacks.seek_func = seek_handler;
         vf.seekable = 1;
         vf.end = ci->id3->filesize;
         vf.ready_state = OPENED;
         vf.links = 1;
    } else {
         DEBUGF("Vorbis: ov_open failed: %d", error);
         error = CODEC_ERROR;
         goto done;
    }

    if (ci->id3->offset) {
        ci->advance_buffer(ci->id3->offset);
        ov_raw_seek(&vf, ci->id3->offset);
        ci->set_elapsed(ov_time_tell(&vf));
        ci->set_offset(ov_raw_tell(&vf));
    }

    previous_section = -1;
    eof = 0;
    while (!eof) {
        ci->yield();
        if (ci->stop_codec || ci->new_track)
            break;

        if (ci->seek_time) {
            if (ov_time_seek(&vf, ci->seek_time - 1)) {
                //ci->logf("ov_time_seek failed");
            }
            ci->seek_complete();
        }

        /* Read host-endian signed 24-bit PCM samples */
        n = ov_read_fixed(&vf, &pcm, 1024, &current_section);

        /* Change DSP and buffer settings for this bitstream */
        if (current_section != previous_section) {
            if (!vorbis_set_codec_parameters(&vf)) {
                error = CODEC_ERROR;
                goto done;
            } else {
                previous_section = current_section;
            }
        }

        if (n == 0) {
            eof = 1;
        } else if (n < 0) {
            DEBUGF("Vorbis: Error decoding frame\n");
        } else {
            ci->pcmbuf_insert(pcm[0], pcm[1], n);
            ci->set_offset(ov_raw_tell(&vf));
            ci->set_elapsed(ov_time_tell(&vf));
        }
    }
    error = CODEC_OK;
    
done:
#if 0 /* defined(SIMULATOR) */
    {
        size_t bufsize;
        void* buf = ci->codec_get_buffer(&bufsize);

        DEBUGF("Vorbis: Memory max: %u\n", get_max_size(buf));
    }
#endif

    if (ci->request_next_track()) {
        /* Clean things up for the next track */
        vf.dataoffsets = NULL;
        vf.offsets = NULL;
        vf.serialnos = NULL;
        vf.pcmlengths = NULL;
        ov_clear(&vf);
        goto next_track;
    }
        
exit:
    ogg_malloc_destroy();
    return error;
}
Esempio n. 12
0
long VorbisDecoder::position() {
    if (!m_data->initialized) return -1;
    double oggpos = ov_time_tell(m_data->vf);
    return (long)(oggpos*1000.0);
}
Esempio n. 13
0
 double getPosition() 
 {
    double pos = ov_time_tell(oggStream);
    return pos * 1000.0;
 }
Esempio n. 14
0
	float OggWrapper::getTime() const
	{
		return static_cast<float>(ov_time_tell(ovFile_));
	}
Esempio n. 15
0
int alogg_get_pos_msecs_ogg(ALOGG_OGG *ogg) {
  return (int)(ov_time_tell(&(ogg->vf)) * 1000);
}
Esempio n. 16
0
int main(){
  OggVorbis_File ov;
  int i,ret;
  ogg_int64_t pcmlength;
  double timelength;
  char *bigassbuffer;
  int dummy;

#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
  _setmode( _fileno( stdin ), _O_BINARY );
#endif


  /* open the file/pipe on stdin */
  if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){
    fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
    exit(1);
  }

  if(ov_seekable(&ov)){

    /* to simplify our own lives, we want to assume the whole file is
       stereo.  Verify this to avoid potentially mystifying users
       (pissing them off is OK, just don't confuse them) */
    for(i=0;i<ov.links;i++){
      vorbis_info *vi=ov_info(&ov,i);
      if(vi->channels!=2){
	fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n"
	       "that are entirely stereo.\n\n");
	exit(1);
      }
    }
    
    /* because we want to do sample-level verification that the seek
       does what it claimed, decode the entire file into memory */
    pcmlength=ov_pcm_total(&ov,-1);
    timelength=ov_time_total(&ov,-1);
    bigassbuffer=malloc(pcmlength*2); /* w00t */
    i=0;
    while(i<pcmlength*2){
      int ret=ov_read(&ov,bigassbuffer+i,pcmlength*2-i,1,1,1,&dummy);
      if(ret<0)continue;
      if(ret){
	i+=ret;
      }else{
	pcmlength=i/2;
      }
      fprintf(stderr,"\rloading.... [%ld left]              ",
	      (long)(pcmlength*2-i));
    }
    
    {
      ogg_int64_t length=ov.end;
      fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n",
	     (long)length);
    
      for(i=0;i<1000;i++){
	ogg_int64_t val=(double)rand()/RAND_MAX*length;
	fprintf(stderr,"\r\t%d [raw position %ld]...     ",i,(long)val);
	ret=ov_raw_seek(&ov,val);
	if(ret<0){
	  fprintf(stderr,"seek failed: %d\n",ret);
	  exit(1);
	}

	_verify(&ov,val,-1,-1.,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n",
	     (long)pcmlength);
    
      for(i=0;i<1000;i++){
	ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
	fprintf(stderr,"\r\t%d [pcm position %ld]...     ",i,(long)val);
	ret=ov_pcm_seek_page(&ov,val);
	if(ret<0){
	  fprintf(stderr,"seek failed: %d\n",ret);
	  exit(1);
	}

	_verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);

      }
    }
    
    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing pcm exact seeking to random places in %ld samples....\n",
	     (long)pcmlength);
    
      for(i=0;i<1000;i++){
	ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
	fprintf(stderr,"\r\t%d [pcm position %ld]...     ",i,(long)val);
	ret=ov_pcm_seek(&ov,val);
	if(ret<0){
	  fprintf(stderr,"seek failed: %d\n",ret);
	  exit(1);
	}
	if(ov_pcm_tell(&ov)!=val){
	  fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
		 (long)val,(long)ov_pcm_tell(&ov));
	  exit(1);
	}

	_verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
	     timelength);
    
      for(i=0;i<1000;i++){
	double val=(double)rand()/RAND_MAX*timelength;
	fprintf(stderr,"\r\t%d [time position %f]...     ",i,val);
	ret=ov_time_seek_page(&ov,val);
	if(ret<0){
	  fprintf(stderr,"seek failed: %d\n",ret);
	  exit(1);
	}

	_verify(&ov,-1,-1,val,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
	     timelength);
    
      for(i=0;i<1000;i++){
	double val=(double)rand()/RAND_MAX*timelength;
	fprintf(stderr,"\r\t%d [time position %f]...     ",i,val);
	ret=ov_time_seek(&ov,val);
	if(ret<0){
	  fprintf(stderr,"seek failed: %d\n",ret);
	  exit(1);
	}
	if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
	  fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n",
		 val,ov_time_tell(&ov));
	  exit(1);
	}

	_verify(&ov,-1,-1,val,pcmlength,bigassbuffer);

      }
    }
    
    fprintf(stderr,"\r                                           \nOK.\n\n");


  }else{
    fprintf(stderr,"Standard input was not seekable.\n");
  }

  ov_clear(&ov);
  return 0;
}
Esempio n. 17
0
unsigned long alogg_get_pos_msecs_ogg_ul(ALOGG_OGG *ogg) {
  return (unsigned long)(ov_time_tell(&(ogg->vf)) * 1000);
}
Esempio n. 18
0
int OggImportFileHandle::Import(TrackFactory *trackFactory, Track ***outTracks,
                                int *outNumTracks, Tags *tags)
{
   wxASSERT(mFile->IsOpened());

   CreateProgress();

   //Number of streams used may be less than mVorbisFile->links,
   //but this way bitstream matches array index.
   mChannels = new WaveTrack **[mVorbisFile->links];

   int i,c;
   for (i = 0; i < mVorbisFile->links; i++)
   {
      //Stream is not used
      if (mStreamUsage[i] == 0)
      {
         //This is just a padding to keep bitstream number and
         //array indices matched.
         mChannels[i] = NULL;
         continue;
      }

      vorbis_info *vi = ov_info(mVorbisFile, i);

      mChannels[i] = new WaveTrack *[vi->channels];

      for (c = 0; c < vi->channels; c++) {
         mChannels[i][c] = trackFactory->NewWaveTrack(int16Sample, vi->rate);

         if (vi->channels == 2) {
            switch (c) {
         case 0:
            mChannels[i][c]->SetChannel(Track::LeftChannel);
            mChannels[i][c]->SetLinked(true);
            break;
         case 1:
            mChannels[i][c]->SetChannel(Track::RightChannel);
            break;
            }
         }
         else {
            mChannels[i][c]->SetChannel(Track::MonoChannel);
         }
      }
   }

/* The number of bytes to get from the codec in each run */
#define CODEC_TRANSFER_SIZE 4096

/* The number of samples to read between calls to the callback.
 * Balance between responsiveness of the GUI and throughput of import. */
#define SAMPLES_PER_CALLBACK 100000

   short *mainBuffer = new short[CODEC_TRANSFER_SIZE];

   /* determine endianness (clever trick courtesy of Nicholas Devillard,
    * (http://www.eso.org/~ndevilla/endian/) */
   int testvar = 1, endian;
   if(*(char *)&testvar)
      endian = 0;  // little endian
   else
      endian = 1;  // big endian

   /* number of samples currently in each channel's buffer */
   int updateResult = eProgressSuccess;
   long bytesRead = 0;
   long samplesRead = 0;
   int bitstream = 0;
   int samplesSinceLastCallback = 0;

   // You would think that the stream would already be seeked to 0, and
   // indeed it is if the file is legit.  But I had several ogg files on
   // my hard drive that have malformed headers, and this added call
   // causes them to be read correctly.  Otherwise they have lots of
   // zeros inserted at the beginning
   ov_pcm_seek(mVorbisFile, 0);
   
   do {
      /* get data from the decoder */
      bytesRead = ov_read(mVorbisFile, (char *) mainBuffer,
                          CODEC_TRANSFER_SIZE,
                          endian,
                          2,    // word length (2 for 16 bit samples)
                          1,    // signed
                          &bitstream);

      if (bytesRead == OV_HOLE) {
         wxFileName f(mFilename);
         wxLogError(wxT("Ogg Vorbis importer: file %s is malformed, ov_read() reported a hole"),
                    f.GetFullName().c_str());
         /* http://lists.xiph.org/pipermail/vorbis-dev/2001-February/003223.html
          * is the justification for doing this - best effort for malformed file,
          * hence the message.
          */
         continue;
      } else if (bytesRead < 0) {
         /* Malformed Ogg Vorbis file. */
         /* TODO: Return some sort of meaningful error. */
         wxLogError(wxT("Ogg Vorbis importer: ov_read() returned error %i"),
                    bytesRead);
         break;
      }

      samplesRead = bytesRead / mVorbisFile->vi[bitstream].channels / sizeof(short);

      /* give the data to the wavetracks */
      if (mStreamUsage[bitstream] != 0)
      {
         for (c = 0; c < mVorbisFile->vi[bitstream].channels; c++)
            mChannels[bitstream][c]->Append((char *)(mainBuffer + c),
            int16Sample,
            samplesRead,
            mVorbisFile->vi[bitstream].channels);
      }

      samplesSinceLastCallback += samplesRead;
      if (samplesSinceLastCallback > SAMPLES_PER_CALLBACK) {
          updateResult = mProgress->Update(ov_time_tell(mVorbisFile),
                                         ov_time_total(mVorbisFile, bitstream));
          samplesSinceLastCallback -= SAMPLES_PER_CALLBACK;

      }
   } while (updateResult == eProgressSuccess && bytesRead != 0);

   delete[]mainBuffer;

   int res = updateResult;
   if (bytesRead < 0)
     res = eProgressFailed;

   if (res == eProgressFailed || res == eProgressCancelled) {
      for (i = 0; i < mVorbisFile->links; i++)
      {
         if (mChannels[i])
         {
            for(c = 0; c < mVorbisFile->vi[bitstream].channels; c++) {
               if (mChannels[i][c])
                  delete mChannels[i][c];
            }
            delete[] mChannels[i];
         }
      }
      delete[] mChannels;
      return res;
   }

   *outNumTracks = 0;
   for (int s = 0; s < mVorbisFile->links; s++)
   {
      if (mStreamUsage[s] != 0)
         *outNumTracks += mVorbisFile->vi[s].channels;
   }

   *outTracks = new Track *[*outNumTracks];
   
   int trackindex = 0;
   for (i = 0; i < mVorbisFile->links; i++)
   {
      if (mChannels[i])
      {
         for (c = 0; c < mVorbisFile->vi[i].channels; c++) {
            mChannels[i][c]->Flush();
            (*outTracks)[trackindex++] = mChannels[i][c];
         }
         delete[] mChannels[i];
      }      
   }
   delete[] mChannels;

   //\todo { Extract comments from each stream? }
   if (mVorbisFile->vc[0].comments > 0) {
      tags->Clear();
      for (c = 0; c < mVorbisFile->vc[0].comments; c++) {
         wxString comment = UTF8CTOWX(mVorbisFile->vc[0].user_comments[c]);
         wxString name = comment.BeforeFirst(wxT('='));
         wxString value = comment.AfterFirst(wxT('='));
         if (name.Upper() == wxT("DATE") && !tags->HasTag(TAG_YEAR)) {
            long val;
            if (value.Length() == 4 && value.ToLong(&val)) {
               name = TAG_YEAR;
            }
         }
         tags->SetTag(name, value);
      }
   }

   return res;
}
Esempio n. 19
0
 int OggStream::getCurrentMS() const
 {
     int r = (int)ov_time_tell(const_cast<OggVorbis_File*>(&_vorbisFile));
     return r;
 }
Esempio n. 20
0
static gboolean vorbis_play (InputPlayback * playback, const gchar * filename,
 VFSFile * file, gint start_time, gint stop_time, gboolean pause)
{
    if (file == NULL)
        return FALSE;

    vorbis_info *vi;
    OggVorbis_File vf;
    gint last_section = -1;
    ReplayGainInfo rg_info;
    gfloat pcmout[PCM_BUFSIZE*sizeof(float)], **pcm;
    gint bytes, channels, samplerate, br;
    gchar * title = NULL;

    seek_value = (start_time > 0) ? start_time : -1;
    stop_flag = FALSE;

    memset(&vf, 0, sizeof(vf));

    gboolean error = FALSE;

    if (ov_open_callbacks (file, & vf, NULL, 0, vfs_is_streaming (file) ?
     vorbis_callbacks_stream : vorbis_callbacks) < 0)
    {
        error = TRUE;
        goto play_cleanup;
    }

    vi = ov_info(&vf, -1);

    if (vi->channels > 2)
        goto play_cleanup;

    br = vi->bitrate_nominal;
    channels = vi->channels;
    samplerate = vi->rate;

    playback->set_params (playback, br, samplerate, channels);

    if (!playback->output->open_audio(FMT_FLOAT, samplerate, channels)) {
        error = TRUE;
        goto play_cleanup;
    }

    if (pause)
        playback->output->pause (TRUE);

    vorbis_update_replaygain(&vf, &rg_info);
    playback->output->set_replaygain_info (& rg_info);

    playback->set_pb_ready(playback);

    /*
     * Note that chaining changes things here; A vorbis file may
     * be a mix of different channels, bitrates and sample rates.
     * You can fetch the information for any section of the file
     * using the ov_ interface.
     */

    while (1)
    {
        if (stop_time >= 0 && playback->output->written_time () >= stop_time)
            goto DRAIN;

        g_mutex_lock (seek_mutex);

        if (stop_flag)
        {
            g_mutex_unlock (seek_mutex);
            break;
        }

        if (seek_value >= 0)
        {
            ov_time_seek (& vf, (double) seek_value / 1000);
            playback->output->flush (seek_value);
            seek_value = -1;
            g_cond_signal (seek_cond);
        }

        g_mutex_unlock (seek_mutex);

        gint current_section = last_section;
        bytes = ov_read_float(&vf, &pcm, PCM_FRAMES, &current_section);
        if (bytes == OV_HOLE)
            continue;

        if (bytes <= 0)
        {
DRAIN:
            while (playback->output->buffer_playing ())
                g_usleep (10000);

            break;
        }

        bytes = vorbis_interleave_buffer (pcm, bytes, channels, pcmout);

        { /* try to detect when metadata has changed */
            vorbis_comment * comment = ov_comment (& vf, -1);
            const gchar * new_title = (comment == NULL) ? NULL :
             vorbis_comment_query (comment, "title", 0);

            if (new_title != NULL && (title == NULL || strcmp (title, new_title)))
            {
                g_free (title);
                title = g_strdup (new_title);

                playback->set_tuple (playback, get_tuple_for_vorbisfile (& vf,
                 filename));
            }
        }

        if (current_section <= last_section) {
            /*
             * The info struct is different in each section.  vf
             * holds them all for the given bitstream.  This
             * requests the current one
             */
            vi = ov_info(&vf, -1);

            if (vi->channels > 2)
                goto stop_processing;

            if (vi->rate != samplerate || vi->channels != channels) {
                samplerate = vi->rate;
                channels = vi->channels;
                while (playback->output->buffer_playing())
                    g_usleep(1000);

                playback->output->close_audio();

                if (!playback->output->open_audio(FMT_FLOAT, vi->rate, vi->channels)) {
                    error = TRUE;
                    goto stop_processing;
                }

                playback->output->flush(ov_time_tell(&vf) * 1000);
                vorbis_update_replaygain(&vf, &rg_info);
                playback->output->set_replaygain_info (& rg_info); /* audio reopened */
            }
        }

        playback->output->write_audio (pcmout, bytes);

stop_processing:

        if (current_section <= last_section)
        {
            playback->set_params (playback, br, samplerate, channels);
            last_section = current_section;
        }
    } /* main loop */

    g_mutex_lock (seek_mutex);
    stop_flag = TRUE;
    g_cond_signal (seek_cond); /* wake up any waiting request */
    g_mutex_unlock (seek_mutex);

    playback->output->close_audio ();

play_cleanup:

    ov_clear(&vf);
    g_free (title);
    return ! error;
}
Esempio n. 21
0
double OggVorbisMusic::getPosition() const
{
  if (!file.isOpen())
    return 0;
  return ov_time_tell(&const_cast<OggVorbis_File&>(vorbisFile));
}
Esempio n. 22
0
static void* player_thread(void* _minfo) 
{
  ogg_t* minfo = (ogg_t*) _minfo;
  
  log_debug("ogg player started");
  
  long current_position_in_ms = 0;
  long previous_position_in_ms = -1; 
  long guard_position_in_ms = -1;
  el_bool playing = el_false;
  
  post_event(minfo->client_notification, AUDIO_READY, current_position_in_ms);
 
  audio_event_t *event;
  event = audio_event_fifo_dequeue(minfo->player_control);
  while (event->state != INTERNAL_CMD_DESTROY) {
    
    audio_state_t event_state = event->state;
    long event_position = event->position_in_ms;
    audio_event_destroy(event);
    
    switch (event_state) {
      case INTERNAL_CMD_LOAD_FILE: {
        playing = el_false;
        if (minfo->is_open) {
          ov_clear(&minfo->vf);
          fclose(minfo->fh);
          aodev_close(minfo->ao_handle);
        }

        minfo->fh = fopen(minfo->file_or_url, "rb");
        if (minfo->fh != NULL) {
          if (ov_open_callbacks(minfo->fh , &minfo->vf, NULL, 0, OV_CALLBACKS_NOCLOSE) < 0) {
            fclose(minfo->fh);
            post_event(minfo->client_notification, AUDIO_NOT_SUPPORTED, -1);
            minfo->is_open = el_false;
          } else {
            minfo->is_open = el_true;
            minfo->can_seek = ov_seekable(&minfo->vf);
            minfo->length = (long) (ov_time_total(&minfo->vf, -1) * 1000.0);
            psem_post(minfo->length_set);
            minfo->current_section = 0;
            vorbis_info* vi = ov_info(&minfo->vf, -1);
            aodev_set_format(minfo->ao_handle, 16, vi->rate, vi->channels);
            aodev_set_endian(minfo->ao_handle, AO_FMT_LITTLE);
            aodev_open(minfo->ao_handle);
          }
        } else {
          post_event(minfo->client_notification, AUDIO_IO_ERROR, -1);
          minfo->is_open = el_false;
        }
        
        current_position_in_ms = 0;
        guard_position_in_ms = -1; 
        
        log_debug("Stream initialized");
          
      }
      break;
      case INTERNAL_CMD_LOAD_URL: {
      }
      break;
      case INTERNAL_CMD_SEEK: {
        ov_time_seek_lap(&minfo->vf, ((double) event_position / 1000.0));
      }
      break;
      case INTERNAL_CMD_PLAY: {
        playing = el_true;
      }
      break;
      case INTERNAL_CMD_PAUSE: {
        playing = el_false;
      }
      break;
      case INTERNAL_CMD_GUARD: {
        guard_position_in_ms = event_position;
      }
      break;
      case INTERNAL_CMD_SET_VOLUME: {
        double scale = ((double) event_position) / 1000.0;
        minfo->volume_scale = scale;
        log_debug2("setting volume to %lf", scale);
      }
      break;
      case INTERNAL_CMD_NONE:
      break;
      default:
      break;
    }
    
    if (guard_position_in_ms >= 0 && current_position_in_ms >= guard_position_in_ms) {

      guard_position_in_ms = -1;
      post_event(minfo->client_notification, AUDIO_GUARD_REACHED, current_position_in_ms);
      
    } else if (playing) {
      if (minfo->is_file) {
        int n = ov_read_filter(&minfo->vf, minfo->buffer, BUFFER_SIZE(minfo), 0, 2, 1, &minfo->current_section,
                               adjust_volume, minfo
                              );
        if (n > 0) {
          aodev_play_buffer(minfo->ao_handle, minfo->buffer, n);
          //log_debug("buffer played");
          
          double tm = ov_time_tell(&minfo->vf);
          current_position_in_ms = (long) (tm * 1000.0);
          
          if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) {
            post_event(minfo->client_notification, AUDIO_PLAYING, current_position_in_ms);
          }
          previous_position_in_ms = current_position_in_ms;
          
        } else {
          post_event(minfo->client_notification, AUDIO_EOS, current_position_in_ms);
          playing = el_false;
        } 
      } else { // Stream playing
        post_event(minfo->client_notification, AUDIO_STATE_ERROR, -1);
        playing = el_false;
      } 
    
    }
    
    if (playing) {
      if (audio_event_fifo_peek(minfo->player_control) != NULL) {
        event = audio_event_fifo_dequeue(minfo->player_control);
      } else {
        event = (audio_event_t*) mc_malloc(sizeof(audio_event_t));
        event->state = INTERNAL_CMD_NONE;
        event->position_in_ms = -1;
      }
    } else {
      event = audio_event_fifo_dequeue(minfo->player_control);
    }
  }

  // destroy event received
  audio_event_destroy(event);

  // exit thread  
  return NULL;
}
Esempio n. 23
0
int VorbisDecoder::GetTimePosition() {
	if (!m_opened) {
		return 0;
	}
	return int(ov_time_tell(&m_file));
}	
Esempio n. 24
0
int alogg_get_pos_secs_oggstream(ALOGG_OGGSTREAM *ogg) {
  return (int)ov_time_tell(&(ogg->vf));
}
Esempio n. 25
0
/////////////////////////////////////////////////////////////////////////////////////////
//Audio callback
/////////////////////////////////////////////////////////////////////////////////////////
static void oggDecodeThread(void *_buf2, unsigned int numSamples, void *pdata){
    short *_buf = (short *)_buf2;
    //static short OGG_mixBuffer[PSP_NUM_AUDIO_SAMPLES * 2 * 2]__attribute__ ((aligned(64)));
    //static unsigned long OGG_tempmixleft = 0;
	int current_section;

	if (OGG_isPlaying) {	// Playing , so mix up a buffer
        outputInProgress = 1;
		while (OGG_tempmixleft < numSamples) {	//  Not enough in buffer, so we must mix more
			unsigned long bytesRequired = (numSamples - OGG_tempmixleft) * 4;	// 2channels, 16bit = 4 bytes per sample
			unsigned long ret = ov_read(&OGG_VorbisFile, (char *) &OGG_mixBuffer[OGG_tempmixleft * 2], bytesRequired, &current_section); //libtremor
            //unsigned long ret = ov_read(&OGG_VorbisFile, (char *) &OGG_mixBuffer[OGG_tempmixleft * 2], bytesRequired, 0, 2, 1, &current_section); //ogg-vorbis
			if (!ret) {	//EOF
                OGG_isPlaying = 0;
				OGG_eos = 1;
                outputInProgress = 0;
				return;
			} else if (ret < 0) {
				if (ret == OV_HOLE)
					continue;
                OGG_isPlaying = 0;
				OGG_eos = 1;
                outputInProgress = 0;
				return;
			}
			OGG_tempmixleft += ret / 4;	// back down to sample num
		}
        OGG_info.instantBitrate = ov_bitrate_instant(&OGG_VorbisFile);
		OGG_milliSeconds = ov_time_tell(&OGG_VorbisFile);

        //Check for playing speed:
        if (OGG_playingSpeed){
            if (ov_raw_seek(&OGG_VorbisFile, ov_raw_tell(&OGG_VorbisFile) + OGG_playingDelta) != 0)
                OGG_setPlayingSpeed(0);
        }

		if (OGG_tempmixleft >= numSamples) {	//  Buffer has enough, so copy across
			int count, count2;
			short *_buf2;
			for (count = 0; count < numSamples; count++) {
				count2 = count + count;
				_buf2 = _buf + count2;
                //Volume boost:
                if (OGG_volume_boost){
                    *(_buf2) = volume_boost(&OGG_mixBuffer[count2], &OGG_volume_boost);
                    *(_buf2 + 1) = volume_boost(&OGG_mixBuffer[count2 + 1], &OGG_volume_boost);
                }else{
                    // Double up for stereo
                    *(_buf2) = OGG_mixBuffer[count2];
                    *(_buf2 + 1) = OGG_mixBuffer[count2 + 1];
                }
			}
			//  Move the pointers
			OGG_tempmixleft -= numSamples;
			//  Now shuffle the buffer along
			for (count = 0; count < OGG_tempmixleft * 2; count++)
			    OGG_mixBuffer[count] = OGG_mixBuffer[numSamples * 2 + count];

		}
        outputInProgress = 0;
    } else {			//  Not Playing , so clear buffer
        int count;
        for (count = 0; count < numSamples * 2; count++)
            *(_buf + count) = 0;
	}
}
Esempio n. 26
0
const int oggDecoder::getRTime( )
{
	return int( ov_time_total( decoder, -1 )-ov_time_tell( decoder ));
}