From 387233792fd7c99e0396409446816ed11594d51d Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 2 May 2003 22:00:09 +0000 Subject: [PATCH] add direct vorbisfile interface --- stepmania/src/RageSoundReader_Vorbisfile.cpp | 158 +++++++++++++++++++ stepmania/src/RageSoundReader_Vorbisfile.h | 31 ++++ 2 files changed, 189 insertions(+) create mode 100644 stepmania/src/RageSoundReader_Vorbisfile.cpp create mode 100644 stepmania/src/RageSoundReader_Vorbisfile.h diff --git a/stepmania/src/RageSoundReader_Vorbisfile.cpp b/stepmania/src/RageSoundReader_Vorbisfile.cpp new file mode 100644 index 0000000000..e41786c8c0 --- /dev/null +++ b/stepmania/src/RageSoundReader_Vorbisfile.cpp @@ -0,0 +1,158 @@ +/* Read from a Vorbisfile interface. Currently targets the Tremor (integer) + * decoder; could be adapted to the regular decoder if needed. */ +#include "global.h" + +#include "RageUtil.h" +#include "SDL_utils.h" +#include "RageSoundReader_Vorbisfile.h" +#include "tremor/ivorbisfile.h" + +#include +#include + + +const int channels = 2; + +/* The amount of data to read from SDL_sound at once. */ +const int read_block_size = 1024; + +bool RageSoundReader_Vorbisfile::Open(CString filename_) +{ + filename=filename_; + + vf = new OggVorbis_File; + FILE *f = fopen(filename, "r"); + if(f == NULL) + { + SetError(ssprintf("ogg fopen(%s) failed: %s", filename.c_str(), strerror(errno))); + return false; + } + + int ret = ov_open(f, vf, NULL, 0); + if(ret < 0) + { + SetError(ssprintf("ogg failed %i", ret)); + fclose(f); + return false; + } + + avail = 0; + + return true; +} + +int RageSoundReader_Vorbisfile::GetLength() const +{ + int len = ov_time_total(vf, -1); + + if(len == OV_EINVAL) + RageException::Throw("RageSoundReader_Vorbisfile::GetLength: ov_time_total returned OV_EINVAL"); + + return len; +} + +int RageSoundReader_Vorbisfile::GetLength_Fast() const +{ + return GetLength(); +} + +int RageSoundReader_Vorbisfile::SetPosition(int ms, bool accurate) +{ + int ret = ov_time_seek(vf, ms); + if(ret < 0) + { + SetError(ssprintf("ogg: SetPosition failed: %i", ret)); + return false; + } + + return ms; +} + +int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len) +{ + int bytes_read = 0; + while(len) + { + if(!avail) + { + vorbis_info *vi = ov_info(vf, -1); + ASSERT(vi != NULL); + + char tmpbuf[4096]; + int bstream; + + int ret = ov_read(vf, tmpbuf, sizeof(tmpbuf), &bstream); +//int ret = 4096; +//memset(tmpbuf, 0, sizeof(tmpbuf)); + if(ret == OV_HOLE) + continue; + if(ret == OV_EBADLINK) + { + SetError(ssprintf("Read: OV_EBADLINK")); + return -1; + } + + if(ret == 0) + return bytes_read; /* EOF */ + + /* If we have a different number of channels, we need to convert. */ + ASSERT(vi->channels == 1 || vi->channels == 2); + if(vi->channels == 1) + { + Sint16 *indata = (Sint16 *)tmpbuf; + Sint16 *outdata = (Sint16 *)buffer; + int size = ret / sizeof(Sint16); + for(unsigned pos = 0; pos < unsigned(size); ++pos) + outdata[pos*2] = outdata[pos*2+1] = indata[pos]; + ret *= 2; + } + else + memcpy(buffer, tmpbuf, ret); /* XXX optimize */ + + avail = ret; + } + + unsigned size = min(avail, len); + memcpy(buf, buffer, size); + + buf += size; + len -= size; + + memmove(buffer, buffer+size, avail-size); + avail -= size; + bytes_read += size; + } + + return bytes_read; +} + +int RageSoundReader_Vorbisfile::GetSampleRate() const +{ + ASSERT(vf); + + vorbis_info *vi = ov_info(vf, -1); + ASSERT(vi != NULL); + + return vi->rate; +} + +RageSoundReader_Vorbisfile::~RageSoundReader_Vorbisfile() +{ + if(vf) + ov_clear(vf); + delete vf; +} + +SoundReader *RageSoundReader_Vorbisfile::Copy() const +{ + RageSoundReader_Vorbisfile *ret = new RageSoundReader_Vorbisfile; + ret->Open(filename); + return ret; +} + +/* +----------------------------------------------------------------------------- + Copyright (c) 2003 by the person(s) listed below. All rights reserved. + Glenn Maynard +----------------------------------------------------------------------------- +*/ diff --git a/stepmania/src/RageSoundReader_Vorbisfile.h b/stepmania/src/RageSoundReader_Vorbisfile.h new file mode 100644 index 0000000000..3fac175db3 --- /dev/null +++ b/stepmania/src/RageSoundReader_Vorbisfile.h @@ -0,0 +1,31 @@ +#ifndef RAGE_SOUND_READER_SDL_SOUND +#define RAGE_SOUND_READER_SDL_SOUND + +#include "RageSoundReader.h" + +typedef struct OggVorbis_File OggVorbis_File; + +class RageSoundReader_Vorbisfile: public SoundReader { + OggVorbis_File *vf; + char buffer[4096*4]; + unsigned avail; + int SetPosition(int ms, bool accurate); + CString filename; + +public: + bool Open(CString filename); + int GetLength() const; + int GetLength_Fast() const; + int SetPosition_Accurate(int ms) { return SetPosition(ms, true); } + int SetPosition_Fast(int ms) { return SetPosition(ms, false); } + int Read(char *buf, unsigned len); + int GetSampleRate() const; + ~RageSoundReader_Vorbisfile(); + SoundReader *Copy() const; +}; + +#endif +/* + * Copyright (c) 2002-2003 by the person(s) listed below. All rights reserved. + * Glenn Maynard + */