Exemple #1
0
    int OggStream::decodeNextBlock(bool looped, void* data, int bufferSize)
    {
        unsigned int bytesUnpacked = 0;

        int p = (int)ov_pcm_tell(&_vorbisFile);

        while (1)
        {
            int r = (int)ov_read(&_vorbisFile, (char*)data, bufferSize, &_section);
            if (!r)
            {
                if (looped)
                {
                    ov_pcm_seek(&_vorbisFile, 0);

                }
                else
                {
                    _streamEnded = true;
                    break;
                }
            }

            data = (char*)data + r;
            bufferSize -= r;

            bytesUnpacked += r;
            if (bufferSize == 0)
                break;
        }

        p = int(ov_pcm_tell(&_vorbisFile)) - p;

        return bytesUnpacked;
    }
Exemple #2
0
void _verify(OggVorbis_File *ov,
             ogg_int64_t val,ogg_int64_t pcmval,double timeval,
             ogg_int64_t pcmlength,
             char *bigassbuffer){
  off_t i;
  int j;
  long bread;
  char buffer[4096];
  int dummy;
  ogg_int64_t pos;
  int hs = ov_halfrate_p(ov);

  /* verify the raw position, the pcm position and position decode */
  if(val!=-1 && ov_raw_tell(ov)<val){
    fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n",
           (long)val,(long)ov_raw_tell(ov));
    exit(1);
  }
  if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
    fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n",
           (long)pcmval,(long)ov_pcm_tell(ov));
    exit(1);
  }
  if(timeval!=-1 && ov_time_tell(ov)>timeval){
    fprintf(stderr,"time position out of tolerance: requested %f, got %f\n",
           timeval,ov_time_tell(ov));
    exit(1);
  }
  pos=ov_pcm_tell(ov);
  if(pos<0 || pos>pcmlength){
    fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos);
    exit(1);
  }
  bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
  for(j=0;j<bread;j++){
    if(buffer[j]!=bigassbuffer[j+((pos>>hs)*2)]){
      fprintf(stderr,"data after seek doesn't match declared pcm position %ld\n",(long)pos);

      for(i=0;i<(pcmlength>>hs)*2-bread;i++){
        for(j=0;j<bread;j++)
          if(buffer[j] != bigassbuffer[i+j])break;
        if(j==bread){
          fprintf(stderr,"data after seek appears to match position %ld\n",(long)((i/2)<<hs));
        }
      }
      {
        FILE *f=fopen("a.m","w");
        for(j=0;j<bread;j++)fprintf(f,"%d %d\n",j,(int)buffer[j]);
        fclose(f);
        f=fopen("b.m","w");
        for(j=-4096;j<bread+4096;j++)
          if(j+((pos*2)>>hs)>=0 && (j+((pos*2)>>hs))<(pcmlength>>hs)*2)
             fprintf(f,"%d %d\n",j,(int)bigassbuffer[j+((pos*2)>>hs)]);
        fclose(f);
      }

      exit(1);
    }
  }
}
void _verify(OggVorbis_File *ov,ogg_int64_t pos,
	     ogg_int64_t val,ogg_int64_t pcmval,
	     ogg_int64_t pcmlength,
	     char *bigassbuffer){
  int j;
  long bread;
  char buffer[4096];
  int dummy;

  /* verify the raw position, the pcm position and position decode */
  if(val!=-1 && ov_raw_tell(ov)<val){
    printf("raw position out of tolerance: requested %ld, got %ld\n",
	   (long)val,(long)ov_raw_tell(ov));
    exit(1);
  }
  if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
    printf("pcm position out of tolerance: requested %ld, got %ld\n",
	   (long)pcmval,(long)ov_pcm_tell(ov));
    exit(1);
  }
  pos=ov_pcm_tell(ov);
  if(pos<0 || pos>pcmlength){
    printf("pcm position out of bounds: got %ld\n",(long)pos);
    exit(1);
  }
  bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
  for(j=0;j<bread;j++){
    if(buffer[j]!=bigassbuffer[j+pos*2]){
      printf("data position after seek doesn't match pcm position\n");
      exit(1);
    }
  }
}
void _verify(OggVorbis_File *ov,
             ogg_int64_t val,
             ogg_int64_t pcmval,
             ogg_int64_t timeval,
             ogg_int64_t pcmlength,
             char *bigassbuffer){
  int j;
  long bread;
  char buffer[4096];
  int dummy;
  ogg_int64_t pos;

  /* verify the raw position, the pcm position and position decode */
  if(val!=-1 && ov_raw_tell(ov)<val){
    fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n",
           (long)val,(long)ov_raw_tell(ov));
    exit(1);
  }
  if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
    fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n",
           (long)pcmval,(long)ov_pcm_tell(ov));
    exit(1);
  }
  if(timeval!=-1 && ov_time_tell(ov)>timeval){
    fprintf(stderr,"time position out of tolerance: requested %ld, got %ld\n",
            (long)timeval,(long)ov_time_tell(ov));
    exit(1);
  }
  pos=ov_pcm_tell(ov);
  if(pos<0 || pos>pcmlength){
    fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos);
    exit(1);
  }
  bread=ov_read(ov,buffer,4096,&dummy);
  if(bigassbuffer){
    for(j=0;j<bread;j++){
      if(buffer[j]!=bigassbuffer[j+pos*4]){
	fprintf(stderr,"data position after seek doesn't match pcm position\n");
	
	{
	  FILE *f=fopen("a.m","w");
	  for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)buffer[j]);
	  fclose(f);
	  f=fopen("b.m","w");
	  for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)bigassbuffer[j+pos*2]);
	  fclose(f);
	}
	
	exit(1);
      }
    }
  }
}
Exemple #5
0
static int
cvorbis_seek_sample (DB_fileinfo_t *_info, int sample) {
    ogg_info_t *info = (ogg_info_t *)_info;
    if (sample < 0) {
        trace ("vorbis: negative seek sample - ignored, but it is a bug!\n");
        return -1;
    }
    if (!info->info.file) {
        trace ("vorbis: file is NULL on seek\n");
        return -1;
    }
    if (sample == 0) {
        deadbeef->pl_lock ();
        const char *filetype = deadbeef->pl_find_meta_raw(info->it, ":FILETYPE");
        if (filetype && strncmp(filetype, "Ogg Vorbis", 10)) {
            sample = 1; // workaround libvorbis bug #1486 (ddb issue #1116)
        }
        deadbeef->pl_unlock ();
    }
    sample += info->it->startsample;
    trace ("vorbis: seek to sample %d\n", sample);
    int res = ov_pcm_seek (&info->vorbis_file, sample);
    if (res != 0 && res != OV_ENOSEEK) {
        trace ("vorbis: error %x seeking to sample %d\n", res, sample);
        return -1;
    }
    int tell = ov_pcm_tell (&info->vorbis_file);
    if (tell != sample) {
        trace ("vorbis: failed to do sample-accurate seek (%d->%d)\n", sample, tell);
    }
    trace ("vorbis: seek successful\n")
    _info->readpos = (float)(sample - info->it->startsample)/_info->fmt.samplerate;
    info->next_update = -2;
    return 0;
}
static GslLong
dh_vorbis_coarse_seek (GslDataHandle *dhandle,
		       GslLong        voffset)
{
  VorbisHandle *vhandle = (VorbisHandle*) dhandle;
  GslLong opos = vhandle->pcm_pos, pos = voffset / dhandle->setup.n_channels;
  
  if (voffset < 0)
    return vhandle->pcm_pos * dhandle->setup.n_channels;

  if (pos < vhandle->pcm_pos ||
      pos >= vhandle->pcm_pos + vhandle->pcm_length + SEEK_BY_READ_AHEAD (vhandle))
    {
      gint err = ov_pcm_seek_page (&vhandle->ofile, vhandle->soffset + pos);

      if (err)	/* eek */
	err = ov_pcm_seek_page (&vhandle->ofile, vhandle->soffset);
      else
	vhandle->pcm_pos = ov_pcm_tell (&vhandle->ofile) - vhandle->soffset;
      if (err || vhandle->pcm_pos < 0)  /* urg, we're completely screwed */
	vhandle->pcm_pos = 0;
      vhandle->pcm_length = 0;
    }
  if (0)
    g_printerr ("OggS-SEEK: at %llu want %llu got %llu (diff-requested %lld)\n",
		opos, pos, vhandle->pcm_pos, pos - opos);

  return vhandle->pcm_pos * dhandle->setup.n_channels;
}
long SoundSourceOggVorbis::seek(long filepos)
{
    // In our speak, filepos is a sample in the file abstraction (i.e. it's
    // stereo no matter what). filepos/2 is the frame we want to seek to.
    if (filepos % 2 != 0) {
        qDebug() << "SoundSourceOggVorbis got non-even seek target.";
        filepos--;
    }

    if (ov_seekable(&vf)) {
        if (ov_pcm_seek(&vf, filepos/2) != 0) {
            // This is totally common (i.e. you're at EOF). Let's not leave this
            // qDebug on.

            // qDebug() << "ogg vorbis: Seek ERR on seekable.";
        }

        // Even if an error occured, return them the current position because
        // that's what we promised. (Double it because ov_pcm_tell returns
        // frames and we pretend to the world that everything is stereo)
        return ov_pcm_tell(&vf) * 2;
    } else {
        qDebug() << "ogg vorbis: Seek ERR at file " << getFilename();
        return 0;
    }
}
Exemple #8
0
int SoundManager::LoadOGG(WAVEFORMATEX* fformat, unsigned char** sample_data, size_t* size_data, char* ogg_path)
{
  FILE *fs;
  if(!(fs=fopen(ogg_path,"rb"))) return 0;

  OggVorbis_File vf;
  if(ov_open(fs,&vf,NULL,0)) return 0;
  vorbis_info* vi=ov_info(&vf,-1);

  int data_len=(int)ov_pcm_total(&vf,-1);
  int start_pos=(int)ov_pcm_tell(&vf);

  int BPS=vi->channels==1?2:4;
  *size_data=(data_len-start_pos)*BPS;

  *sample_data=new unsigned char[*size_data];

  size_t decoded=0;

  while (decoded < *size_data) {
    int curr;
    decoded += ov_read(&vf,(char*)(*sample_data)+decoded,(*size_data)-decoded,0,2,1,&curr);
  }

  fformat->wFormatTag=WAVE_FORMAT_PCM;
  fformat->nChannels=vi->channels;
  fformat->nSamplesPerSec=vi->rate;
  fformat->wBitsPerSample=16;
  fformat->nBlockAlign=vi->channels*fformat->wBitsPerSample/8;
  fformat->nAvgBytesPerSec=fformat->nBlockAlign*vi->rate;
  fformat->cbSize=0;

  return 1;
}
int RageSoundReader_Vorbisfile::GetNextSourceFrame() const
{
	ASSERT(vf != NULL);

	int iFrame = (int)ov_pcm_tell( vf );
	return iFrame;
}
Exemple #10
0
LONGLONG ovd_get_current(HANDLE hov)
{
	LIBOV_STRUCT* lov = (LIBOV_STRUCT*)hov;
	if (!lov) return FALSE;

	return ov_pcm_tell(&lov->vf);
}
RageSoundReader_FileReader::OpenResult RageSoundReader_Vorbisfile::Open( RageFileBasic *pFile )
{
	m_pFile = pFile;
	vf = new OggVorbis_File;
	memset( vf, 0, sizeof(*vf) );

	ov_callbacks callbacks;
	callbacks.read_func  = OggRageFile_read_func;
	callbacks.seek_func  = OggRageFile_seek_func;
	callbacks.close_func = OggRageFile_close_func;
	callbacks.tell_func  = OggRageFile_tell_func;

	int ret = ov_open_callbacks( pFile, vf, NULL, 0, callbacks );
	if( ret < 0 )
	{
		SetError( ov_ssprintf(ret, "ov_open failed") );
		delete vf;
		vf = NULL;
		switch( ret )
		{
		case OV_ENOTVORBIS:
			return OPEN_UNKNOWN_FILE_FORMAT;
		default:
			return OPEN_FATAL_ERROR;
		}
	}

	eof = false;
	read_offset = (int) ov_pcm_tell(vf);

	vorbis_info *vi = ov_info( vf, -1 );
	channels = vi->channels;

	return OPEN_OK;
}
Exemple #12
0
int dxpSoundOggDecode(DXPAVCONTEXT *av)
{
#ifdef DXP_BUILDOPTION_USE_LIBOGG
	int len = dxpSoundCalcBufferSize(av, dxpSoundGetNextSampleNum(av));
//	int readbytes = 0;
	int ret, bitstream;
	vorbis_info *vi;
	u8 *pcmOut = av->pcmOut;
	if(av->format != DXP_SOUNDFMT_OGG)return -1;
	if(len <= 0)return -1; // EOF
	while(len > 0)
	{
		ret = ov_read(av->ogg.file,(char*)pcmOut,len,&bitstream);
		if(ret == OV_HOLE)continue;
		if(ret == OV_EBADLINK)return -1;
		vi = ov_info(av->ogg.file, -1);
		if(!vi || vi->channels != av->channels)return -1; // error
		pcmOut += ret;
//		readbytes += ret;
		len -= ret;
		if(ret == 0) len = 0; // EOF
	}
//	av->nextPos += readbytes / dxpSoundCalcBufferSize(av, 1);
	av->nextPos = (int)ov_pcm_tell(av->ogg.file);
	return 0;
#else
	return -1;
#endif
}
Exemple #13
0
float
AudioManager::Player::GetPosition()
{
    boost::recursive_mutex::scoped_lock lock( *m_UpdateMutex );

    int play_offset;
    alGetSourcei( m_Source, AL_SAMPLE_OFFSET, &play_offset );
    return ( ov_pcm_tell( &m_VorbisFile ) - ( m_ChannelBufferNumber * m_ChannelBufferSize / m_VorbisInfo->channels / sizeof( int16_t ) - play_offset ) ) * 1000 / m_VorbisInfo->rate;
}
Exemple #14
0
float GetVorbisTime(MFAudioStream *pStream)
{
	MFVorbisStream *pVS = (MFVorbisStream*)pStream->pStreamData;
#if defined(VORBIS_TREMOR)
	return (float)ov_pcm_tell(&pVS->vorbisFile) / (float)pVS->pInfo->rate;
#else
	return (float)ov_time_tell(&pVS->vorbisFile);
#endif
}
Exemple #15
0
gc_int32 gauX_sample_source_ogg_tell(void* in_context, gc_int32* out_totalSamples)
{
  gau_SampleSourceOggContext* ctx = &((gau_SampleSourceOgg*)in_context)->context;
  gc_int32 ret;
  gc_mutex_lock(ctx->oggMutex);
  /* TODO: Decide whether to support total samples for OGG files */
  if(out_totalSamples)
    *out_totalSamples = ov_pcm_total(&ctx->oggFile, -1); /* Note: This isn't always valid when the stream is poorly-formatted */
  ret = (gc_int32)ov_pcm_tell(&ctx->oggFile);
  gc_mutex_unlock(ctx->oggMutex);
  return ret;
}
bool COggVorbisFileHelper::set_current_timepos( double pos )
{
	if(vf.datasource && vf.seekable)
	{
		if(nStatus == OH_PLAYING)
		{
			s3eSoundChannelPause(nSoundChannel);
			s3eDeviceYield(1);
#if defined(HAVE_PTHREAD)
			if(mDecThread.thread_status == CThread::TRUNNING)	pthread_mutex_lock(&mutex1);
#endif
			ov_time_seek_func(&vf,pos);
			current_time = pos;
			current_sample = (ogg_int64_t) (ov_pcm_tell(&vf) * dResampleFactor*get_nChannels());
#if defined(HAVE_PTHREAD)
			if(mDecThread.thread_status == CThread::TRUNNING)	pthread_mutex_unlock(&mutex1);
#endif
			nStatus = OH_BUFFERING;
			mDecBuffer->Clear();
			Wait_counter(0);
			s3eSoundChannelResume(nSoundChannel);
		}
		else
		{
#if defined(HAVE_PTHREAD)
			if(mDecThread.thread_status == CThread::TRUNNING)	pthread_mutex_lock(&mutex1);
#endif
			ov_time_seek_func(&vf,pos);
			current_time = pos;
			current_sample = (ogg_int64_t) (ov_pcm_tell(&vf) * dResampleFactor*get_nChannels());
#if defined(HAVE_PTHREAD)
			if(mDecThread.thread_status == CThread::TRUNNING)	pthread_mutex_unlock(&mutex1);
#endif
			mDecBuffer->Clear();
		}

		return true;
	}
	return false;
}
Exemple #17
0
int dxpSoundOggSeek(DXPAVCONTEXT *av,int sample)
{
#ifdef DXP_BUILDOPTION_USE_LIBOGG
	int ret;
	if(av->format != DXP_SOUNDFMT_OGG)return -1;
	ret = ov_pcm_seek(av->ogg.file,(ogg_int64_t)sample);
	if(ret < 0)return -1;
	av->nextPos = (int)ov_pcm_tell(av->ogg.file);
	return 0;
#else
	return -1;
#endif
}
    //-----------------------------------------------------------------------------
    size_t MusicStream::_getCurrentPos()
    {
        // <todo> This method is not working with OGG files smaller than
        // BUFFER_SIZE (fix it)
        if (mMusic != 0)
        {
            int alPos,buffers;
            size_t streamPos     = static_cast<size_t>(ov_pcm_tell(&mFile));
            size_t loopPoint     = Database::getSingleton().musics[mMusic-1].
                    loopPoint;
            size_t sizeInSamples = BUFFER_SIZE/2;
            size_t offset        = 666666666;

            if ((int)streamPos == OV_EINVAL)
            {
                SONETTO_THROW("Failed telling current stream offset in music file ("+
                        Ogre::StringConverter::toString(streamPos)+")");
            }

            if (sizeInSamples > mStreamLen)
            {
                sizeInSamples = mStreamLen;
            }

            alGetSourcei(mMusicSrc,AL_SAMPLE_OFFSET,&alPos);
            mAudioMan->_alErrorCheck("MusicStream::_getCurrentPos()",
                    "Failed getting music source sample offset");

            alGetSourcei(mMusicSrc,AL_BUFFERS_PROCESSED,&buffers);
            mAudioMan->_alErrorCheck("MusicStream::_getCurrentPos()",
                    "Failed getting number of processed buffers in music source");

            alPos -= buffers*sizeInSamples;
            if (streamPos < loopPoint || streamPos-loopPoint > sizeInSamples) {
                offset = streamPos-(sizeInSamples-alPos);
            } else {
                size_t warped   = streamPos-loopPoint;
                size_t unwarped = sizeInSamples-warped;

                if ((size_t)alPos >= unwarped) {
                    offset = streamPos-(sizeInSamples-alPos);
                } else {
                    offset = mStreamLen-(sizeInSamples-alPos);
                }
            }

            return offset;
        }

        return 0;
    }
Exemple #19
0
/*!
 * \brief Tell the current position in OGG/Vorbis filestream measured in pcms.
 * \param fs The filestream to take action on.
 * \return 0 or greater with the position measured in samples, or -1 for false.
 */
static off_t ogg_vorbis_tell(struct ast_filestream *fs)
{
	off_t pos;
	struct ogg_vorbis_desc *desc = (struct ogg_vorbis_desc *) fs->_private;

	if (desc->writing) {
		return desc->writing_pcm_pos;
	}

	if ((pos = ov_pcm_tell(&desc->ov_f)) < 0) {
		return -1;
	}
	return pos;
}
SoundReader_FileReader::OpenResult RageSoundReader_Vorbisfile::Open(CString filename_)
{
	filename=filename_;

	vf = new OggVorbis_File;
	memset( vf, 0, sizeof(*vf) );

	RageFile *f = new RageFile;
	
	if( !f->Open( filename ) )
	{
		SetError( ssprintf("ogg: opening \"%s\" failed: %s", filename.c_str(), f->GetError().c_str()) );
		delete f;
		delete vf;
		vf = NULL;
		return OPEN_FATAL_ERROR;
	}

	ov_callbacks callbacks;
	callbacks.read_func  = OggRageFile_read_func;
	callbacks.seek_func  = OggRageFile_seek_func;
	callbacks.close_func = OggRageFile_close_func;
	callbacks.tell_func  = OggRageFile_tell_func;

	int ret = ov_open_callbacks( f, vf, NULL, 0, callbacks );
	if(ret < 0)
	{
		SetError( ov_ssprintf(ret, "ov_open failed") );
		delete f;
		delete vf;
		vf = NULL;
		switch( ret )
		{
		case OV_ENOTVORBIS:
			return OPEN_UNKNOWN_FILE_FORMAT;
		default:
			return OPEN_FATAL_ERROR;
		}
	}

	eof = false;
	read_offset = (int) ov_pcm_tell(vf);

	vorbis_info *vi = ov_info( vf, -1 );
	ASSERT_M( vi->channels == 1 || vi->channels == 2, ssprintf("%i", vi->channels) );
	channels = vi->channels;

    return OPEN_OK;
}
static inline unsigned int getCurrentSample(struct OggVorbisDecoderState* decoder)
{
#ifndef WZ_NOSOUND
	int samplePos;

	ASSERT(decoder != NULL, "NULL decoder passed!");

	samplePos = ov_pcm_tell(&decoder->oggVorbis_stream);

	if (samplePos == OV_EINVAL)
		return 0;

	return samplePos;
#else
	return 0;
#endif
}
static void
read_packet (VorbisHandle *vhandle)
{
  gfloat **pcm = NULL;
  gint stream_id, i;
  
  vhandle->pcm_pos = ov_pcm_tell (&vhandle->ofile) - vhandle->soffset;
  vhandle->pcm_length = ov_read_float (&vhandle->ofile, &pcm, G_MAXINT, &stream_id);
  if (vhandle->pcm_pos < 0 || vhandle->pcm_length < 0 || stream_id != vhandle->bitstream)
    {
      /* urg, this is bad! */
      dh_vorbis_coarse_seek (&vhandle->dhandle, 0);
    }
  else
    for (i = 0; i < vhandle->dhandle.setup.n_channels; i++)
      vhandle->pcm[i] = pcm[i];
}
Exemple #23
0
//This function will stream new Ogg data to a specified buffer at a specified position
bool DIZ_OGGSTREAM::streamToBuffer(ALuint buf, int *location) {
	//Declare a stream-data buffer
	char data[DEFAULT_BUFFER_SIZE];
	//Declare our tracking variables for our streaming progress
	int size = 0, result;
	//And declare a bitstream variable
	int bitstream;

	//First, seek to our desired starting position in the stream
	ov_pcm_seek(&oggFile, *location);
	//Loop until we've filled up our desired buffer size
	while (size < DEFAULT_BUFFER_SIZE) {
		//Read as much new data as we can into the buffer
		result = ov_read(&oggFile, data + size, DEFAULT_BUFFER_SIZE - size, 0, 2, 1, &bitstream);
		//Now set our stream-location to our current spot
		*location = (int)ov_pcm_tell(&oggFile);
		
		//If our result was positive, it's our amount of data read
		if (result > 0) {
			size += result;
		//If our result was negative, it's an error
		}else if (result < 0) {
			return false;
		//If our result was 0, we've hit the end of the file
		}else {
			break;
		}
	}

	//If size is 0, then we're obviously trying to read from the end of the file, so return false
	if (size == 0) {
		return false;
	}

	//Then load our new data into our buffer
	alBufferData(buf, format, data, size, vorbisInfo->rate);

	//Then double-check for an OpenAL error
	if (alGetError() != AL_NO_ERROR) {
		return false;
	}

	//And exit
	return true;
}
void CSoundRender_Source::decompress		(u32 line, OggVorbis_File* ovf)
{
	VERIFY	(ovf);
	// decompression of one cache-line
	u32		line_size		= SoundRender->cache.get_linesize();
	char*	dest			= (char*)	SoundRender->cache.get_dataptr	(CAT,line);
	u32		buf_offs		= (psSoundFreq==sf_22K)?(line*line_size):(line*line_size)/2;
	u32		left_file		= dwBytesTotal - buf_offs;
	u32		left			= (u32)_min	(left_file,line_size);
	// seek
	u32	cur_pos				= u32	(ov_pcm_tell(ovf));
	if (cur_pos!=buf_offs){
		ov_pcm_seek			(ovf,buf_offs);
	}
	// decompress
	if (psSoundFreq==sf_22K)i_decompress_hr(ovf,dest,left);
	else					i_decompress_fr(ovf,dest,left);
}
Exemple #25
0
size_t
OggSoundFile::read(void* _buffer, size_t buffer_size)
{
    char*  buffer         = reinterpret_cast<char*> (_buffer);
    int    section        = 0;
    size_t totalBytesRead = 0;

    while(buffer_size>0) {
#ifdef WORDS_BIGENDIAN
        int bigendian = 1;
#else
        int bigendian = 0;
#endif

        size_t bytes_to_read    = buffer_size;
        if(loop_at > 0) {
            size_t      bytes_per_sample       = 2;
            ogg_int64_t time                   = ov_pcm_tell(&vorbis_file);
            ogg_int64_t samples_left_till_loop = loop_at - time;
            ogg_int64_t bytes_left_till_loop
                = samples_left_till_loop * bytes_per_sample;
            if(bytes_left_till_loop <= 4)
                break;

            if(bytes_left_till_loop < (ogg_int64_t) bytes_to_read) {
                bytes_to_read    = (size_t) bytes_left_till_loop;
            }
        }

        long bytesRead
            = ov_read(&vorbis_file, buffer, bytes_to_read, bigendian,
                      2, 1, &section);
        if(bytesRead == 0) {
            break;
        }
        buffer_size    -= bytesRead;
        buffer         += bytesRead;
        totalBytesRead += bytesRead;
    }

    return totalBytesRead;
}
SINT SoundSourceOggVorbis::seekSampleFrame(
        SINT frameIndex) {
    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    DEBUG_ASSERT(isValidFrameIndex(frameIndex));

    const int seekResult = ov_pcm_seek(&m_vf, frameIndex);
    if (0 == seekResult) {
        m_curFrameIndex = frameIndex;
    } else {
        qWarning() << "Failed to seek OggVorbis file:" << seekResult;
        const ogg_int64_t pcmOffset = ov_pcm_tell(&m_vf);
        if (0 <= pcmOffset) {
            m_curFrameIndex = pcmOffset;
        } else {
            // Reset to EOF
            m_curFrameIndex = getMaxFrameIndex();
        }
    }

    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    return m_curFrameIndex;
}
int RageSoundReader_Vorbisfile::SetPosition( int iFrame )
{
	eof = false;

	const ogg_int64_t sample = ogg_int64_t(iFrame);

	int ret = ov_pcm_seek( vf, sample );
	if(ret < 0)
	{
		/* Returns OV_EINVAL on EOF. */
		if( ret == OV_EINVAL )
		{
			eof = true;
			return 0;
		}
		SetError( ov_ssprintf(ret, "ogg: SetPosition failed") );
		return -1;
	}
	read_offset = (int) ov_pcm_tell(vf);

	return 1;
}
Exemple #28
0
int dxpSoundOggInit(DXPAVCONTEXT *av)
{
#ifdef DXP_BUILDOPTION_USE_LIBOGG
	ov_callbacks callbacks;
	vorbis_info *vi;
	int ret;
	av->ogg.file = (OggVorbis_File*)malloc(sizeof(OggVorbis_File));
	if(!av->ogg.file)return -1;
	memset(av->ogg.file,0,sizeof(OggVorbis_File));
	callbacks.read_func = ogg_read_func;
	callbacks.seek_func = ogg_seek_func;
	callbacks.close_func = ogg_close_func;
	callbacks.tell_func = ogg_tell_func;
	FileRead_seek(av->fileHandle, 0, SEEK_SET);
	ret = ov_open_callbacks(&av->fileHandle,av->ogg.file,NULL,0,callbacks);
	if(ret < 0)
	{
		free(av->ogg.file);
		return -1;
	}
	vi = ov_info(av->ogg.file, -1);
	if(!vi || (vi->channels != 1 && vi->channels != 2))
	{
		ov_clear(av->ogg.file);
		free(av->ogg.file);
		return -1;
	}
	av->sampleSize = 2;
	av->channels = (u8)vi->channels;
	av->sampleRate = (int)vi->rate;
	av->nextPos = (int)ov_pcm_tell(av->ogg.file);
	av->outSampleNum = 1024;
	av->format = DXP_SOUNDFMT_OGG;
	return 0;
#else
	return -1;
#endif
}
int RageSoundReader_Vorbisfile::Read( float *buf, int iFrames )
{
	int frames_read = 0;

	while( iFrames && !eof )
	{
		const int bytes_per_frame = sizeof(float)*channels;

		int iFramesRead = 0;

		{
			int curofs = (int) ov_pcm_tell(vf);
			if( curofs < read_offset )
			{
				/* The timestamps moved backwards.  Ignore it.  This file probably
				 * won't sync correctly. */
				LOG->Trace( "p ahead %p %i < %i, we're ahead by %i", 
					this, curofs, read_offset, read_offset-curofs );
				read_offset = curofs;
			}
			else if( curofs > read_offset )
			{
				/* Our offset doesn't match.  We have a hole in the data, or corruption.
				 * If we're reading with accurate syncing, insert silence to line it up.
				 * That way, corruptions in the file won't casue desyncs. */

				/* In bytes: */
				int iSilentFrames = curofs - read_offset;
				iSilentFrames = min( iSilentFrames, (int) iFrames );
				int silence = iSilentFrames * bytes_per_frame;
				CHECKPOINT_M( ssprintf("p %i,%i: %i frames of silence needed", curofs, read_offset, silence) );

				memset( buf, 0, silence );
				iFramesRead = iSilentFrames;
			}
		}

		if( iFramesRead == 0 )
		{
			int bstream;
#if defined(INTEGER_VORBIS)
			int ret = ov_read( vf, (char *) buf, iFrames * channels * sizeof(int16_t), &bstream );
#else // float vorbis decoder
			float **pcm;
			int ret = ov_read_float( vf, &pcm, iFrames, &bstream );
#endif

			{
				vorbis_info *vi = ov_info( vf, -1 );
				ASSERT( vi != NULL );

				if( (unsigned) vi->channels != channels )
					RageException::Throw( "File \"%s\" changes channel count from %i to %i; not supported.",
							      filename.c_str(), channels, (int)vi->channels );
			}


			if( ret == OV_HOLE )
				continue;
			if( ret == OV_EBADLINK )
			{
				SetError( ssprintf("Read: OV_EBADLINK") );
				return ERROR;
			}

			if( ret == 0 )
			{
				eof = true;
				continue;
			}

#if defined(INTEGER_VORBIS)
			if( ret > 0 )
			{
				int iSamplesRead = ret / sizeof(int16_t);
				iFramesRead = iSamplesRead / channels;

				/* Convert in reverse, so we can do it in-place. */
				const int16_t *pIn = (int16_t *) buf;
				float *pOut = (float *) buf;
				for( int i = iSamplesRead-1; i >= 0; --i )
					pOut[i] = pIn[i] / 32768.0f;
			}
#else
			if( ret > 0 )
			{
				iFramesRead = ret;

				int iNumChannels = channels;
				for( int iChannel = 0; iChannel < iNumChannels; ++iChannel )
				{
					const float *pChannelIn = pcm[iChannel];
					float *pChannelOut = &buf[iChannel];
					for( int i = 0; i < iFramesRead; ++i )
					{
						*pChannelOut = *pChannelIn;
						++pChannelIn;
						pChannelOut += iNumChannels;
					}
				}
			}
#endif
		}

		read_offset += iFramesRead;

		buf += iFramesRead * channels;
		frames_read += iFramesRead;
		iFrames -= iFramesRead;
	}

	if( !frames_read )
		return END_OF_FILE;

	return frames_read;
}