aboutsummaryrefslogtreecommitdiff
path: root/sound/vorbis.cpp
diff options
context:
space:
mode:
authorLars Persson2005-12-01 19:14:38 +0000
committerLars Persson2005-12-01 19:14:38 +0000
commita6b7333b33a1879d31c1c9c069fa1aeb508490d3 (patch)
treede43253f59d1de810d24eea14523ec9f0cf3aad1 /sound/vorbis.cpp
parent81eed2207555ed60f04d183bce4e79f29a3a650c (diff)
downloadscummvm-rg350-a6b7333b33a1879d31c1c9c069fa1aeb508490d3.tar.gz
scummvm-rg350-a6b7333b33a1879d31c1c9c069fa1aeb508490d3.tar.bz2
scummvm-rg350-a6b7333b33a1879d31c1c9c069fa1aeb508490d3.zip
Working Vorbis support for Symbian OS
svn-id: r19725
Diffstat (limited to 'sound/vorbis.cpp')
-rw-r--r--sound/vorbis.cpp105
1 files changed, 88 insertions, 17 deletions
diff --git a/sound/vorbis.cpp b/sound/vorbis.cpp
index 3cb9a45248..6466ef23de 100644
--- a/sound/vorbis.cpp
+++ b/sound/vorbis.cpp
@@ -73,6 +73,16 @@ static size_t read_wrap(void *ptr, size_t size, size_t nmemb, void *datasource)
file_info *f = (file_info *) datasource;
int result;
+#ifdef __SYMBIAN32__
+ // For symbian we must check that an alternative file pointer is created, see if its open
+ // If not re-open file and seek to the last read position
+ if(f->file && !f->file->isOpen()){
+ f->file->open(f->file->name());
+ f->file->seek(f->curr_pos);
+ }
+#endif
+
+
nmemb *= size;
if (f->curr_pos > (int) f->len)
nmemb = 0;
@@ -82,6 +92,12 @@ static size_t read_wrap(void *ptr, size_t size, size_t nmemb, void *datasource)
// the file, so make sure the current position is what we think it is.
f->file->seek(f->start + f->curr_pos);
result = f->file->read(ptr, nmemb);
+#ifdef __SYMBIAN32__
+ // For symbian we now store the last read position and then close the file
+ if(f->file){
+ f->file->close();
+ }
+#endif
if (result == -1) {
f->curr_pos = f->file->pos() - f->start;
return (size_t) -1;
@@ -101,8 +117,25 @@ static int seek_wrap(void *datasource, ogg_int64_t offset, int whence) {
whence = SEEK_SET;
}
+#ifdef __SYMBIAN32__
+ // For symbian we must check that an alternative file pointer is created, see if its open
+ // If not re-open file and seek to the last read position
+ if(f->file && !f->file->isOpen()){
+ f->file->open(f->file->name());
+ f->file->seek(f->curr_pos);
+ }
+#endif
+
f->file->seek(offset, whence);
f->curr_pos = f->file->pos() - f->start;
+
+#ifdef __SYMBIAN32__
+ // For symbian we now store the last read position and then close the file
+ if(f->file){
+ f->file->close();
+ }
+#endif
+
return f->curr_pos;
}
@@ -126,6 +159,7 @@ static ov_callbacks g_File_wrap = {
VorbisTrackInfo::VorbisTrackInfo(File *file) {
+debug(5, "" __FILE__ ":%i", __LINE__);
_file = file;
if (openTrack()) {
@@ -140,28 +174,43 @@ VorbisTrackInfo::VorbisTrackInfo(File *file) {
}
bool VorbisTrackInfo::openTrack() {
+debug(5, "" __FILE__ ":%i", __LINE__);
assert(_file);
file_info *f = new file_info;
- f->file = _file;
+#if defined(__SYMBIAN32__)
+ // Symbian can't share filehandles between different threads.
+ // So create a new file and seek that to the other filehandles position
+ f->file= new (ELeave)File;
+ f->file->open(_file->name());
+ f->file->seek(_file->pos());
+#else
+ f->file = _file;
+#endif
+
f->start = 0;
f->len = _file->size();
f->curr_pos = 0;
_file->seek(0);
bool err = (ov_open_callbacks((void *) f, &_ov_file, NULL, 0, g_File_wrap) < 0);
-
if (err) {
+#ifdef __SYMBIAN32__
+ delete f->file;
+#endif
delete f;
} else {
- _file->incRef();
- }
+#ifndef __SYMBIAN32__
+ _file->incRef();
+#endif
+ }
return err;
}
VorbisTrackInfo::~VorbisTrackInfo() {
+debug(5, "" __FILE__ ":%i", __LINE__);
if (! _error_flag) {
ov_clear(&_ov_file);
_file->decRef();
@@ -169,14 +218,18 @@ VorbisTrackInfo::~VorbisTrackInfo() {
}
void VorbisTrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration) {
-
+debug(5, "" __FILE__ ":%i", __LINE__);
bool err = openTrack();
assert(!err);
-#ifdef USE_TREMOR
- ov_time_seek(&_ov_file, (ogg_int64_t)(startFrame / 75.0 * 1000));
+#ifdef USE_TREMOR // In Tremor, the ov_time_seek() and ov_time_seek_page() calls take seeking positions in milliseconds as 64 bit integers, rather than in seconds as doubles as in Vorbisfile.
+#if defined(__SYMBIAN32__) && defined(__GCC32__) // SumthinWicked says: fixing "relocation truncated to fit: ARM_26 __fixdfdi" during linking on GCC, see portdefs.h
+ ov_time_seek(&_ov_file, (ogg_int64_t)scumm_fixdfdi(startFrame / 75.0 * 1000));
+#else
+ ov_time_seek(&_ov_file, (ogg_int64_t)(startFrame / 75.0 * 1000));
+#endif
#else
- ov_time_seek(&_ov_file, startFrame / 75.0);
+ ov_time_seek(&_ov_file, startFrame / 75.0);
#endif
AudioStream *input = makeVorbisStream(&_ov_file, duration * ov_info(&_ov_file, -1)->rate / 75);
@@ -184,6 +237,7 @@ void VorbisTrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int
}
DigitalTrackInfo *getVorbisTrack(int track) {
+debug(5, "" __FILE__ ":%i", __LINE__);
char track_name[32];
File *file = new File();
@@ -234,6 +288,7 @@ VorbisInputStream::VorbisInputStream(OggVorbis_File *file, int duration, bool de
: _ov_file(file),
_bufferEnd(_buffer + ARRAYSIZE(_buffer)),
_deleteFileAfterUse(deleteFileAfterUse) {
+debug(5, "" __FILE__ ":%i", __LINE__);
// Check the header, determine if this is a stereo stream
_numChannels = ov_info(_ov_file, -1)->channels;
@@ -249,16 +304,19 @@ VorbisInputStream::VorbisInputStream(OggVorbis_File *file, int duration, bool de
}
VorbisInputStream::~VorbisInputStream() {
+debug(5, "" __FILE__ ":%i", __LINE__);
ov_clear(_ov_file);
if (_deleteFileAfterUse)
delete _ov_file;
}
inline bool VorbisInputStream::eosIntern() const {
+debug(5, "" __FILE__ ":%i", __LINE__);
return _pos >= _bufferEnd;
}
int VorbisInputStream::readBuffer(int16 *buffer, const int numSamples) {
+debug(5, "" __FILE__ ":%i", __LINE__);
int samples = 0;
while (samples < numSamples && !eosIntern()) {
const int len = MIN(numSamples - samples, (int)(_bufferEnd - _pos));
@@ -274,13 +332,14 @@ int VorbisInputStream::readBuffer(int16 *buffer, const int numSamples) {
}
void VorbisInputStream::refill() {
+debug(5, "" __FILE__ ":%i", __LINE__);
// Read the samples
uint len_left = sizeof(_buffer);
char *read_pos = (char *)_buffer;
while (len_left > 0 && _end_pos > ov_pcm_tell(_ov_file)) {
long result = ov_read(_ov_file, read_pos, len_left,
-#ifndef USE_TREMOR
+#ifndef USE_TREMOR // Tremor ov_read() always returns data as signed 16 bit interleaved PCM in host byte order. As such, it does not take arguments to request specific signedness, byte order or bit depth as in Vorbisfile.
#ifdef SCUMM_BIG_ENDIAN
1,
#else
@@ -311,15 +370,25 @@ void VorbisInputStream::refill() {
}
static AudioStream *makeVorbisStream(OggVorbis_File *file, int duration) {
+debug(5, "" __FILE__ ":%i", __LINE__);
return new VorbisInputStream(file, duration, false);
}
AudioStream *makeVorbisStream(File *file, uint32 size) {
+debug(5, "" __FILE__ ":%i", __LINE__);
OggVorbis_File *ov_file = new OggVorbis_File;
file_info *f = new file_info;
- f->file = file;
- f->start = file->pos();
+#if defined(__SYMBIAN32__)
+ // Symbian can't share filehandles between different threads.
+ // So create a new file and seek that to the other filehandles position
+ f->file= new (ELeave)File;
+ f->file->open(file->name());
+ f->file->seek(file->pos());
+#else
+ f->file = file;
+#endif
+ f->start = file->pos();
f->len = size;
f->curr_pos = 0;
@@ -327,11 +396,13 @@ AudioStream *makeVorbisStream(File *file, uint32 size) {
warning("Invalid file format");
delete ov_file;
delete f;
- return 0;
- } else {
- file->incRef();
- return new VorbisInputStream(ov_file, 0, true);
- }
-}
+ return 0;
+ } else {
+#ifndef __SYMBIAN32__
+ file->incRef();
+#endif
+ return new VorbisInputStream(ov_file, 0, true);
+ }
+ }
#endif