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;
}
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;
}
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;
}