[Scummvm-cvs-logs] CVS: scummvm mp3_cd.cpp,NONE,1.1 mp3_cd.h,NONE,1.1 sdl.cpp,1.71,1.72 x11.cpp,1.8,1.9
Nicolas Bacca
arisme at users.sourceforge.net
Thu Apr 4 22:45:08 CEST 2002
Update of /cvsroot/scummvm/scummvm
In directory usw-pr-cvs1:/tmp/cvs-serv1233
Modified Files:
sdl.cpp x11.cpp
Added Files:
mp3_cd.cpp mp3_cd.h
Log Message:
MP3 CD patch reorganized
--- NEW FILE: mp3_cd.cpp ---
/* ScummVM - Scumm Interpreter
* Copyright (C) 2002 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/mp3_cd.cpp,v 1.1 2002/04/05 00:00:45 arisme Exp $
*/
#include "stdafx.h"
#include "scumm.h"
#include "mp3_cd.h"
#ifdef COMPRESSED_SOUND_FILE
int _current_mp3_cd_track;
struct xing _vbr_header;
struct mad_header _mad_header;
long _mp3_size;
FILE *_mp3_track;
MixerChannel *_mc;
// From xing.c in MAD
int xing_parse(struct xing *xing, struct mad_bitptr ptr, unsigned int bitlen)
{
xing->flags = 0;
if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC)
goto fail;
xing->flags = mad_bit_read(&ptr, 32);
bitlen -= 64;
if (xing->flags & XING_FRAMES) {
if (bitlen < 32)
goto fail;
xing->frames = mad_bit_read(&ptr, 32);
bitlen -= 32;
}
if (xing->flags & XING_BYTES) {
if (bitlen < 32)
goto fail;
xing->bytes = mad_bit_read(&ptr, 32);
bitlen -= 32;
}
if (xing->flags & XING_TOC) {
int i;
if (bitlen < 800)
goto fail;
for (i = 0; i < 100; ++i)
xing->toc[i] = (unsigned char)mad_bit_read(&ptr, 8);
bitlen -= 800;
}
if (xing->flags & XING_SCALE) {
if (bitlen < 32)
goto fail;
xing->scale = mad_bit_read(&ptr, 32);
bitlen -= 32;
}
return 0;
fail:
xing->flags = 0;
return -1;
}
// Borrowed from Winamp plugin in_mad.c
BOOL parse_xing_vbr_tag()
{
struct mad_stream stream;
struct mad_frame frame;
unsigned char buffer[8192];
unsigned int buflen = 0;
int count = 0, result = 0;
_vbr_header.flags = 0;
mad_stream_init(&stream);
mad_frame_init(&frame);
fseek(_mp3_track, 0, SEEK_SET);
while (1) {
if (buflen < sizeof(buffer)) {
DWORD bytes;
bytes = fread(buffer + buflen, 1, sizeof(buffer) - buflen, _mp3_track);
if (bytes <= 0) {
if (bytes == -1)
result = -1;
break;
}
buflen += bytes;
}
mad_stream_buffer(&stream, buffer, buflen);
while (1) {
if (mad_frame_decode(&frame, &stream) == -1) {
if (!MAD_RECOVERABLE(stream.error))
break;
if (stream.error != MAD_ERROR_BADCRC)
continue;
}
if (count++ ||
xing_parse(&_vbr_header, stream.anc_ptr, stream.anc_bitlen)
== -1)
break;
}
if (count || stream.error != MAD_ERROR_BUFLEN)
break;
memmove(buffer, stream.next_frame,
buflen = &buffer[buflen] - stream.next_frame);
}
if (count)
memcpy(&_mad_header, &frame.header, sizeof(mad_header));
else
result = -1;
mad_frame_finish(&frame);
mad_stream_finish(&stream);
return (result != -1);
}
uint32 calc_cd_file_offset(int start_frame) {
long offset;
if (!_vbr_header.flags) {
float frame_size;
//mad_timer_t timer; - recode with timer
/* Constant bit rate - perhaps not fully accurate */
frame_size = (float)144 * _mad_header.bitrate / _mad_header.samplerate;
offset = (long)((float)start_frame / (float)CD_FPS * 1000 /
(float)((float)1152 / (float)_mad_header.samplerate * 1000) *
(float)(frame_size + 0.5));
}
else {
/* DOES NOT WORK AT THE MOMENT */
/* see Xing SDK */
long a;
float fa, fb, fx;
float percent = (float)start_frame / (float)CD_FPS * 1000 /
((float)((float)1152 / (float)_mad_header.samplerate * 1000) * _vbr_header.frames) *
100;
if( percent < 0.0f ) percent = 0.0f;
if( percent > 100.0f ) percent = 100.0f;
a = (int)percent;
if( a > 99 ) a = 99;
fa = _vbr_header.toc[a];
if( a < 99 ) {
fb = _vbr_header.toc[a+1];
}
else {
fb = 256.0f;
}
fx = fa + (fb-fa)*(percent-a);
offset = (int)((1.0f/256.0f)*fx*_vbr_header.bytes);
}
return offset;
}
BOOL mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame) {
// See if we are already playing this track, else try to open it
if (_current_mp3_cd_track != track) {
char track_name[1024];
sprintf(track_name, "%strack%d.mp3", s->_gameDataPath, track);
_mp3_track = fopen(track_name, "rb");
if (!_mp3_track) {
warning("No CD and track %d not available in mp3 format", track);
return FALSE;
}
if (!parse_xing_vbr_tag()) {
warning("Error parsing file header - ignoring file",
track);
fclose(_mp3_track);
return FALSE;
}
if (_vbr_header.flags) {
if (!(
(_vbr_header.flags & XING_TOC) &&
(_vbr_header.flags & XING_BYTES) &&
(_vbr_header.flags & XING_FRAMES)
)) {
warning("Missing required part of VBR header - ignoring file");
fclose(_mp3_track);
_vbr_header.flags = 0;
return FALSE;
}
}
// Allocate the music mixer if necessary
if (!_mc) {
_mc = s->allocateMixer();
if (!_mc) {
warning("No mixer channel available for MP3 music");
return FALSE;
}
}
fseek(_mp3_track, 0, SEEK_END);
_mp3_size = ftell(_mp3_track);
fseek(_mp3_track, 0, SEEK_SET);
_mc->type = MIXER_MP3_CDMUSIC;
_mc->sound_data.mp3_cdmusic.file = _mp3_track;
_mc->sound_data.mp3_cdmusic.playing = FALSE;
_mc->sound_data.mp3_cdmusic.buffer_size = 200000;
_mc->_sfx_sound = malloc(_mc->sound_data.mp3_cdmusic.buffer_size);
/* see if it's enough */
mad_stream_init(&_mc->sound_data.mp3.stream);
if (_mad_header.samplerate == 44100)
mad_stream_options((mad_stream*)&_mc->sound_data.mp3.stream,
MAD_OPTION_HALFSAMPLERATE);
mad_frame_init(&_mc->sound_data.mp3.frame);
mad_synth_init(&_mc->sound_data.mp3.synth);
_current_mp3_cd_track = track;
}
if (_current_mp3_cd_track == track) {
uint32 where;
// See where we want to go
where = calc_cd_file_offset(start_frame);
if (start_frame < 0 || end_frame < 0) {
warning("Negative index in frame");
return FALSE;
}
mad_timer_set(&_mc->sound_data.mp3_cdmusic.duration,
0,
end_frame,
CD_FPS);
fseek(_mp3_track, where, SEEK_SET);
_mc->sound_data.mp3_cdmusic.playing = TRUE;
return TRUE;
}
return FALSE;
}
#endif
--- NEW FILE: mp3_cd.h ---
/* ScummVM - Scumm Interpreter
* Copyright (C) 2002 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/mp3_cd.h,v 1.1 2002/04/05 00:00:46 arisme Exp $
*/
#ifndef MP3_CD_H
#define MP3_CD_H
// From xing.h in MAD
# define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
struct xing {
long flags; /* valid fields (see below) */
unsigned long frames; /* total number of frames */
unsigned long bytes; /* total number of bytes */
unsigned char toc[100]; /* 100-point seek table */
long scale; /* ?? */
};
enum {
XING_FRAMES = 0x00000001L,
XING_BYTES = 0x00000002L,
XING_TOC = 0x00000004L,
XING_SCALE = 0x00000008L
};
BOOL mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame);
#endif
Index: sdl.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sdl.cpp,v
retrieving revision 1.71
retrieving revision 1.72
diff -C2 -d -r1.71 -r1.72
*** sdl.cpp 4 Apr 2002 22:47:03 -0000 1.71
--- sdl.cpp 5 Apr 2002 00:00:46 -0000 1.72
***************
*** 30,33 ****
--- 30,34 ----
#include "cdmusic.h"
+ #include "mp3_cd.h"
static unsigned int scale;
***************
*** 677,997 ****
static Uint32 cd_end_time, cd_stop_time, cd_next_second;
! #ifdef COMPRESSED_SOUND_FILE
!
! // MP3 CD track support
!
!
! // From xing.h in MAD
!
! # define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
!
! struct xing {
! long flags; /* valid fields (see below) */
! unsigned long frames; /* total number of frames */
! unsigned long bytes; /* total number of bytes */
! unsigned char toc[100]; /* 100-point seek table */
! long scale; /* ?? */
! };
!
! enum {
! XING_FRAMES = 0x00000001L,
! XING_BYTES = 0x00000002L,
! XING_TOC = 0x00000004L,
! XING_SCALE = 0x00000008L
! };
!
!
! int _current_mp3_cd_track;
! struct xing _vbr_header;
! struct mad_header _mad_header;
! long _mp3_size;
! FILE *_mp3_track;
! MixerChannel *_mc;
!
! // From xing.c in MAD
!
! int xing_parse(struct xing *xing, struct mad_bitptr ptr, unsigned int bitlen)
! {
!
! xing->flags = 0;
!
! if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC)
! goto fail;
!
! xing->flags = mad_bit_read(&ptr, 32);
! bitlen -= 64;
!
! if (xing->flags & XING_FRAMES) {
! if (bitlen < 32)
! goto fail;
!
! xing->frames = mad_bit_read(&ptr, 32);
! bitlen -= 32;
! }
!
! if (xing->flags & XING_BYTES) {
! if (bitlen < 32)
! goto fail;
!
! xing->bytes = mad_bit_read(&ptr, 32);
! bitlen -= 32;
! }
!
! if (xing->flags & XING_TOC) {
! int i;
!
! if (bitlen < 800)
! goto fail;
!
! for (i = 0; i < 100; ++i)
! xing->toc[i] = (unsigned char)mad_bit_read(&ptr, 8);
!
! bitlen -= 800;
! }
!
! if (xing->flags & XING_SCALE) {
! if (bitlen < 32)
! goto fail;
!
! xing->scale = mad_bit_read(&ptr, 32);
! bitlen -= 32;
! }
!
! return 0;
!
! fail:
! xing->flags = 0;
! return -1;
! }
!
! // Borrowed from Winamp plugin in_mad.c
!
! BOOL parse_xing_vbr_tag()
! {
! struct mad_stream stream;
! struct mad_frame frame;
! unsigned char buffer[8192];
! unsigned int buflen = 0;
! int count = 0, result = 0;
!
! _vbr_header.flags = 0;
!
! mad_stream_init(&stream);
! mad_frame_init(&frame);
!
! fseek(_mp3_track, 0, SEEK_SET);
!
! while (1) {
! if (buflen < sizeof(buffer)) {
! DWORD bytes;
!
! bytes = fread(buffer + buflen, 1, sizeof(buffer) - buflen, _mp3_track);
! if (bytes <= 0) {
! if (bytes == -1)
! result = -1;
! break;
! }
!
! buflen += bytes;
! }
!
! mad_stream_buffer(&stream, buffer, buflen);
!
! while (1) {
! if (mad_frame_decode(&frame, &stream) == -1) {
! if (!MAD_RECOVERABLE(stream.error))
! break;
!
! if (stream.error != MAD_ERROR_BADCRC)
! continue;
! }
!
! if (count++ ||
! xing_parse(&_vbr_header, stream.anc_ptr, stream.anc_bitlen)
! == -1)
! break;
! }
!
! if (count || stream.error != MAD_ERROR_BUFLEN)
! break;
!
! memmove(buffer, stream.next_frame,
! buflen = &buffer[buflen] - stream.next_frame);
! }
!
! if (count)
! memcpy(&_mad_header, &frame.header, sizeof(mad_header));
! else
! result = -1;
!
! mad_frame_finish(&frame);
! mad_stream_finish(&stream);
!
! return (result != -1);
! }
!
! uint32 calc_cd_file_offset(int start_frame) {
! long offset;
!
! if (!_vbr_header.flags) {
! float frame_size;
! //mad_timer_t timer; - recode with timer
!
! /* Constant bit rate - perhaps not fully accurate, recheck */
! frame_size = (float)(144 * _mad_header.bitrate / _mad_header.samplerate);
! offset = (float)(float)start_frame / (float)CD_FPS * 1000 /
! (float)((float)1152 / (float)_mad_header.samplerate * 1000) *
! (float)(frame_size + 0.5);
! }
! else {
! /* DOES NOT WORK AT THE MOMENT */
! /* see Xing SDK */
! long a;
! float fa, fb, fx;
! float percent = (float)start_frame / (float)CD_FPS * 1000 /
! ((float)((float)1152 / (float)_mad_header.samplerate * 1000) * _vbr_header.frames) *
! 100;
!
! if( percent < 0.0f ) percent = 0.0f;
! if( percent > 100.0f ) percent = 100.0f;
!
! a = (int)percent;
! if( a > 99 ) a = 99;
! fa = _vbr_header.toc[a];
! if( a < 99 ) {
! fb = _vbr_header.toc[a+1];
! }
! else {
! fb = 256.0f;
! }
!
! fx = fa + (fb-fa)*(percent-a);
!
! offset = (int)((1.0f/256.0f)*fx*_vbr_header.bytes);
!
! }
!
! return offset;
! }
!
!
! #endif
!
! void real_cd_play(int track, int num_loops, int start_frame, int end_frame) {
! // warning("cd_play(%d,%d,%d,%d)", track, num_loops, start_frame, end_frame);
! if (!cdrom) return;
!
! cd_track = track;
! cd_num_loops = num_loops;
! cd_start_frame = start_frame;
!
! SDL_CDStatus(cdrom);
! SDL_CDPlayTracks(cdrom, track, start_frame, 0, end_frame);
! cd_end_frame = end_frame;
! cd_stop_time = 0;
! cd_end_time = SDL_GetTicks() +
! cdrom->track[track].length * 1000 / CD_FPS;
! }
!
! void cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame) {
! scumm->_vars[14] = 0;
#ifdef COMPRESSED_SOUND_FILE
! // See if we are already playing this track, else try to open it
!
! if (_current_mp3_cd_track != track) {
! char track_name[1024];
!
! sprintf(track_name, "%strack%d.mp3", s->_gameDataPath, track);
! _mp3_track = fopen(track_name, "rb");
! if (!_mp3_track) {
! warning("No CD and track %d not available in mp3 format", track);
! real_cd_play(track, num_loops, start_frame, end_frame);
! return;
! }
!
! if (!parse_xing_vbr_tag()) {
! warning("Error parsing file header - ignoring file",
! track);
! fclose(_mp3_track);
! real_cd_play(track, num_loops, start_frame, end_frame);
! return;
! }
!
! if (_vbr_header.flags) {
! if (!(
! (_vbr_header.flags & XING_TOC) &&
! (_vbr_header.flags & XING_BYTES) &&
! (_vbr_header.flags & XING_FRAMES)
! )) {
! warning("Missing required part of VBR header - ignoring file");
! fclose(_mp3_track);
! _vbr_header.flags = 0;
! real_cd_play(track, num_loops, start_frame, end_frame);
! return;
! }
! }
!
! // Allocate the music mixer if necessary
!
! if (!_mc) {
! _mc = s->allocateMixer();
! if (!_mc) {
! warning("No mixer channel available for MP3 music");
! real_cd_play(track, num_loops, start_frame, end_frame);
! return;
! }
! }
!
! fseek(_mp3_track, 0, SEEK_END);
! _mp3_size = ftell(_mp3_track);
! fseek(_mp3_track, 0, SEEK_SET);
!
! _mc->type = MIXER_MP3_CDMUSIC;
! _mc->sound_data.mp3_cdmusic.file = _mp3_track;
! _mc->sound_data.mp3_cdmusic.playing = FALSE;
! _mc->sound_data.mp3_cdmusic.buffer_size = 200000;
! _mc->_sfx_sound = malloc(_mc->sound_data.mp3_cdmusic.buffer_size);
!
! /* see if it's enough */
! mad_stream_init(&_mc->sound_data.mp3.stream);
! if (_mad_header.samplerate == 44100)
! mad_stream_options((mad_stream*)&_mc->sound_data.mp3.stream,
! MAD_OPTION_HALFSAMPLERATE);
!
! mad_frame_init(&_mc->sound_data.mp3.frame);
! mad_synth_init(&_mc->sound_data.mp3.synth);
!
! _current_mp3_cd_track = track;
! }
!
!
! if (_current_mp3_cd_track == track) {
!
! uint32 where;
!
! // See where we want to go
! where = calc_cd_file_offset(start_frame);
!
! if (start_frame < 0 || end_frame < 0) {
! warning("Negative index in frame");
! return;
! }
! mad_timer_set(&_mc->sound_data.mp3_cdmusic.duration,
! 0,
! end_frame,
! CD_FPS);
! fseek(_mp3_track, where, SEEK_SET);
! _mc->sound_data.mp3_cdmusic.playing = TRUE;
!
! return;
! }
! #endif
!
! real_cd_play(track, num_loops, start_frame, end_frame);
}
--- 678,704 ----
static Uint32 cd_end_time, cd_stop_time, cd_next_second;
! void cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame) {
#ifdef COMPRESSED_SOUND_FILE
! if (mp3_cd_play(s, track, num_loops, start_frame, end_frame))
! return;
! #endif
! // warning("cd_play(%d,%d,%d,%d)", track, num_loops, start_frame, end_frame);
! if (!cdrom) return;
! scumm->_vars[14] = 0;
! cd_track = track;
! cd_num_loops = num_loops;
! cd_start_frame = start_frame;
!
! SDL_CDStatus(cdrom);
! SDL_CDPlayTracks(cdrom, track, start_frame, 0, end_frame);
! cd_end_frame = end_frame;
! cd_stop_time = 0;
! cd_end_time = SDL_GetTicks() +
! cdrom->track[track].length * 1000 / CD_FPS;
}
Index: x11.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/x11.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** x11.cpp 4 Apr 2002 22:47:03 -0000 1.8
--- x11.cpp 5 Apr 2002 00:00:46 -0000 1.9
***************
*** 27,30 ****
--- 27,31 ----
#include "sound.h"
#include "cdmusic.h"
+ #include "mp3_cd.h"
#include <sys/time.h>
***************
*** 188,192 ****
/* No CD on the iPAQ => stub functions */
void cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame) {
! /* Insert SDL.cpp MP3 code here :) */
}
int cd_is_running(void) {
--- 189,196 ----
/* No CD on the iPAQ => stub functions */
void cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame) {
!
! #ifdef COMPRESSED_SOUND_FILE
! mp3_cd_play(s, track, num_loops, start_frame, end_frame);
! #endif
}
int cd_is_running(void) {
More information about the Scummvm-git-logs
mailing list