Update libgme to 0.6.2

This commit is contained in:
Steel Titanium 2018-12-30 22:49:11 -05:00
parent 80e30c6aaa
commit f73501fd11
23 changed files with 142 additions and 313 deletions

Binary file not shown.

Binary file not shown.

View file

@ -4,7 +4,7 @@ project(libgme)
include (CheckCXXCompilerFlag) include (CheckCXXCompilerFlag)
# When version is changed, also change the one in gme/gme.h to match # When version is changed, also change the one in gme/gme.h to match
set(GME_VERSION 0.6.0 CACHE INTERNAL "libgme Version") set(GME_VERSION 0.6.2 CACHE INTERNAL "libgme Version")
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't. # 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
# Of course, 2.4 might work, in which case you're welcome to drop # Of course, 2.4 might work, in which case you're welcome to drop
@ -57,6 +57,8 @@ if (USE_GME_NSFE AND NOT USE_GME_NSF)
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE) SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
endif() endif()
option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
# Check for GCC "visibility" support. # Check for GCC "visibility" support.
if (CMAKE_COMPILER_IS_GNUCXX) if (CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY) check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
@ -79,10 +81,10 @@ if (CMAKE_COMPILER_IS_GNUCXX)
endif() endif()
endif() endif()
endif() # test visibility endif() # test visibility
endif (CMAKE_COMPILER_IS_GNUCXX)
# Cache this result # Cache this result
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility") set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
endif (CMAKE_COMPILER_IS_GNUCXX)
# Shared library defined here # Shared library defined here
add_subdirectory(gme) add_subdirectory(gme)

View file

@ -1,262 +1,5 @@
Game_Music_Emu Change Log Game_Music_Emu Change Log
------------------------- -------------------------
Game_Music_Emu 0.6.0 Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
-------------------- for the accurate change log.
- Note: A 0.5.6 release was referenced but never tagged or packaged.
- SPC improvements:
- Switched to newer snes_spc 0.9.0 for SPC emulation. Uses fast DSP.
- Fixed Spc_Emu::gain().
- Fixed support for files <0x10200 bytes.
- Other bugfixes:
- Fixed a couple of GBS bugs, one involving access of memory after
realloc.
- Blip_Buffer works on systems where 'double' is a single-precision
floating-point type.
- Fix uninitialized buffer size in dual_resampler.
- Compilation warnings squashed out as of clang 3.3-pre and gcc 4.7.2.
- API changes/additions:
- Removed documentation of C++ interface, as the C interface in gme.h is
the only supported one.
- Added gme_enable_accuracy() for enabling more accurate sound emulation
options (currently affects SPC only).
- Build system improvements:
- Add pkg_config support.
- Fix build on case-insensitive systems.
- Allow for install on Cygwin.
- Fix install on multilib systems, such as many 64-bit distros (CMake must
be able to figure out your system's libsuffix, if any).
- C++ implementation symbols are not leaked into the resultant library
file (requires symbol visibility support).
- Sample player improvements:
- Can toggle fast/accurate emulation (with the 'A' key).
Game_Music_Emu 0.5.5
--------------------
- CMake build support has been added. You can build Game_Music_Emu as
a shared library and install it so that you do not have to include your
own copy if you know libgme will be present on your target system.
Requires CMake 2.6 or higher.
Game_Music_Emu 0.5.2
--------------------
- *TONS* of changes and improvements. You should re-read the new header
files and documentation as the changes will allow you to simplify your
code a lot (it might even be simpler to just rewrite it). Existing code
should continue to work without changes in most cases (see Deprecated
features in gme.txt).
- New file formats: AY, HES, KSS, SAP, NSFE
- All-new comprehensive C interface (also usable from C++). Simplifies
many things, especially file loading, and brings everything together in
one header file (gme.h).
- Information tags and track names and times can be accessed for all
game music formats
- New features supported by all emulators: end of track fading,
automatic silence detection, adjustable song tempo, seek to new time in
track
- Updated mini player example to support track names and times, echo,
tempo, and channel muting, and added visual waveform display
- Improved configuration to use blargg_config.h, which you can modify
and keep when you update to a newer libary version. Includes flag for
library to automatically handle gzipped files using zlib (so you don't
need to use Gzip_File_Reader anymore).
- GBS: Fixed wave channel to not reset waveform when APU is powered off
(affected Garfield). Also improved invalid bank selection (affected Game
& Watch and others).
- VGM: Added support for alternate noise shifter register
configurations, used by other systems like the BBC Micro.
- SPC: Removed IPL ROM dump from emulator, as none of the SPC files I
scanned needed it, and an SPC file can include a copy if necessary. Also
re-enabled supposed clamping in gaussian interpolation between the third
and fourth lookups, though I don't know whether it matters
- Added Music_Emu::load_mem() to use music data already in memory
(without copying it)
- Added Music_Emu::warning(), which reports minor problems when loading
and playing a music file
- Added Music_Emu::set_gain() for uniform adjustment of gain. Can only
be set during initialization, so not useful as a general volume control.
- Added custom operator new to ensure that no exceptions are thrown in
the library (I'd use std::nothrow if it were part of pre-ISO (ARM) C++)
- Added BLIP_BUFFER_FAST flag to blargg_config.h to use a lower quality
bandlimited synthesis in "classic" emulators, which might help
performance on ancient processors (measure first!). Don't use this
unless absolutely necessary, as quality suffers.
- Improved performance a bit for x86 platforms
- Text files now in DOS newline format so they will open in Notepad
properly
- Removed requirement that file header structures not have any padding
added to the end
- Fixed common bug in all CPU emulators where negative program counter
could crash emulator (occurred during a negative branch from the
beginning of memory). Also fixed related bug in Z80 emulator for
IX/IY+displacement mode.
- Eliminated all warnings when compiling on gcc 4.0. The following
generates no diagnostics:
gcc -S gme/*.cpp -o /dev/null -ansi -fno-gnu-keywords
-fno-nonansi-builtins -pedantic -W -Wabi -Wall -Wcast-align
-Wcast-qual -Wchar-subscripts -Wdisabled-optimization -Werror
-Winline -Wlong-long -Wmultichar -Winvalid-offsetof
-Wnon-virtual-dtor -Woverloaded-virtual -Wparentheses
-Wpointer-arith -Wredundant-decls -Wreorder -Wsign-compare
-Wsign-promo -Wunknown-pragmas -Wwrite-strings
Game_Music_Emu 0.3.0
--------------------
- Added more demos, including music player using the SDL multimedia
library for sound, and improved documentation
- All: Improved interface to emulators to allow simpler setup and
loading. Instead of various init() functions, all now support
set_sample_rate( long rate ) and load( const char* file_path ).
- All: Removed error return from start_track() and play(), and added
error_count() to get the total number of emulation errors since the
track was last started. See demos for examples of new usage.
- All: Fixed mute_voices() muting to be preserved after loading files
and starting tracks, instead of being cleared as it was whenever a track
was started
- VGM: Rewrote Vgm_Emu to support Sega Genesis/Mega Drive FM sound at
any sample rate with optional FM oversampling, support for alternate
YM2612 sound cores, and support for optional YM2413
- VGM: Added tempo control, useful for slowing 60Hz NTSC Sega Genesis
music to 50Hz PAL
- VGM: Removed Vgm_Emu::track_data(), since I realized that this
information is already present in the VGM header (oops!)
- GYM: Changed Gym_Emu::track_length() operation (see Gym_Emu.h)
- NSF: Added support for Sunsoft FME-7 sound chip used by Gimmick
soundtrack
- NSF: Fixed Namco 106 problems with Final Lap and others
- Moved library sources to gme/ directory to reduce clutter, and merged
boost/ functionality into blargg_common.h
- Added Gzip_File_Reader for transparently using gzipped files
Game_Music_Emu 0.2.4
--------------------
- Created a discussion forum for problems and feedback:
http://groups-beta.google.com/group/blargg-sound-libs
- Changed error return value of Blip_Buffer::sample_rate() (also for
Stereo_Buffer, Effects_Buffer, etc.) to blargg_err_t (defined in
blargg_common.h), to make error reporting consistent with other
functions. This means the "no error" return value is the opposite of
what it was before, which will break current code which checks the error
return value:
// current code (broken)
if ( !buf.sample_rate( samples_per_sec ) )
out_of_memory();
// quick-and-dirty fix (just remove the ! operation)
if ( buf.sample_rate( samples_per_sec ) )
out_of_memory();
// proper fix
blargg_err_t error = buf.sample_rate( samples_per_sec );
if ( error )
report_error( error );
- Implemented workaround for MSVC++ 6 compiler limitations, allowing it
to work on that compiler again
- Added sample clamping to avoid wrap-around at high volumes, allowing
higher volume with little distortion
- Added to-do list and design notes
- Added Music_Emu::skip( long sample_count ) to skip ahead in current
track
- Added Gym_Emu::track_length() and Vgm_Emu::track_length() for
determining the length of non-looped GYM and VGM files
- Partially implemented DMC non-linearity when its value is directly set
using $4011, which reduces previously over-emphasized "popping" of
percussion on some games (TMNT II in particular)
- Fixed Fir_Resampler, used for SPC and GYM playback (was incorrectly
using abs() instead of fabs()...argh)
- Fixed SPC emulation bugs: eliminated clicks in Plok! soundtrack and
now stops sample slightly earlier than the end, as the SNES does. Fixed
a totally broken CPU addressing mode.
- Fixed Konami VRC6 saw wave (was very broken before). Now VRC6 music
sounds decent
- Fixed a minor GBS emulation bug
- Fixed GYM loop point bug when track was restarted before loop point
had been reached
- Made default GBS frequency equalization less muffled
- Added pseudo-surround effect removal for SPC files
- Added Music_Emu::voice_names() which returns names for each voice.
- Added BLARGG_SOURCE_BEGIN which allows custom compiler options to be
easily set for library sources
- Changed assignment of expansion sound chips in Nsf_Emu to be spread
more evenly when using Effects_Buffer
- Changed 'size_t' values in Blip_Buffer interface to 'long'
- Changed demo to generate a WAVE sound file rather than an AIFF file
Game_Music_Emu 0.2.0
--------------------
- Redid framework and rewrote/cleaned up emulators
- Changed licensing to GNU Lesser General Public License (LGPL)
- Added Sega Genesis GYM and Super Nintendo SPC emulators
- Added Namco-106 and Konami VRC6 sound chip support to NSF emulator
- Eliminated use of static mutable data in emulators, allowing
multi-instance safety
Game_Music_Emu 0.1.0
--------------------
- First release

View file

@ -1,7 +1,5 @@
/* C example that opens a game music file and records 10 seconds to "out.wav" */ /* C example that opens a game music file and records 10 seconds to "out.wav" */
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
#include "gme/gme.h" #include "gme/gme.h"
#include "Wave_Writer.h" /* wave_ functions for writing sound file */ #include "Wave_Writer.h" /* wave_ functions for writing sound file */
@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
void handle_error( const char* str ); void handle_error( const char* str );
int main() int main(int argc, char *argv[])
{ {
const char *filename = "test.nsf"; /* Default file to open */
if ( argc >= 2 )
filename = argv[1];
long sample_rate = 44100; /* number of samples per second */ long sample_rate = 44100; /* number of samples per second */
int track = 0; /* index of track to play (0 = first) */ /* index of track to play (0 = first) */
int track = argc >= 3 ? atoi(argv[2]) : 0;
/* Open music file in new emulator */ /* Open music file in new emulator */
Music_Emu* emu; Music_Emu* emu;

View file

@ -1,7 +1,5 @@
// C++ example that opens a game music file and records 10 seconds to "out.wav" // C++ example that opens a game music file and records 10 seconds to "out.wav"
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
#include "gme/Music_Emu.h" #include "gme/Music_Emu.h"
#include "Wave_Writer.h" #include "Wave_Writer.h"
@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
void handle_error( const char* str ); void handle_error( const char* str );
int main() int main(int argc, char *argv[])
{ {
const char *filename = "test.nsf"; /* Default file to open */
if ( argc >= 2 )
filename = argv[1];
long sample_rate = 44100; // number of samples per second long sample_rate = 44100; // number of samples per second
int track = 0; // index of track to play (0 = first) // index of track to play (0 = first)
int track = argc >= 3 ? atoi(argv[2]) : 0;
// Determine file type // Determine file type
gme_type_t file_type; gme_type_t file_type;

View file

@ -1,10 +1,10 @@
Game_Music_Emu 0.6.0 Game_Music_Emu 0.6.2
-------------------- --------------------
Author : Shay Green <gblargg@gmail.com> Author : Shay Green <gblargg@gmail.com>
Website: http://www.slack.net/~ant/libs/ Maintainer : Michael Pyne <mpyne@purinchu.net>
Forum : http://groups.google.com/group/blargg-sound-libs Website : https://bitbucket.org/mpyne/game-music-emu/
Source : https://code.google.com/p/game-music-emu/ Source : https://bitbucket.org/mpyne/game-music-emu/
License: GNU Lesser General Public License (LGPL) License : GNU Lesser General Public License (LGPL), see LICENSE.txt
Contents Contents
-------- --------

View file

@ -143,7 +143,7 @@ add_definitions(-DBLARGG_BUILD_DLL)
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Add library to be compiled. # Add library to be compiled.
add_library(gme SHARED ${libgme_SRCS}) add_library(gme ${libgme_SRCS})
# The version is the release. The "soversion" is the API version. As long # The version is the release. The "soversion" is the API version. As long
# as only build fixes are performed (i.e. no backwards-incompatible changes # as only build fixes are performed (i.e. no backwards-incompatible changes
@ -159,4 +159,4 @@ install(TARGETS gme LIBRARY DESTINATION lib${LIB_SUFFIX}
ARCHIVE DESTINATION lib) # DLL platforms ARCHIVE DESTINATION lib) # DLL platforms
install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme) install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib/pkgconfig) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig)

View file

@ -22,8 +22,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
const char Data_Reader::eof_error [] = "Unexpected end of file"; const char Data_Reader::eof_error [] = "Unexpected end of file";
#define RETURN_VALIDITY_CHECK( cond ) \
do { if ( unlikely( !(cond) ) ) return "Corrupt file"; } while(0)
blargg_err_t Data_Reader::read( void* p, long s ) blargg_err_t Data_Reader::read( void* p, long s )
{ {
RETURN_VALIDITY_CHECK( s > 0 );
long result = read_avail( p, s ); long result = read_avail( p, s );
if ( result != s ) if ( result != s )
{ {
@ -38,6 +43,8 @@ blargg_err_t Data_Reader::read( void* p, long s )
blargg_err_t Data_Reader::skip( long count ) blargg_err_t Data_Reader::skip( long count )
{ {
RETURN_VALIDITY_CHECK( count >= 0 );
char buf [512]; char buf [512];
while ( count ) while ( count )
{ {
@ -54,7 +61,8 @@ long File_Reader::remain() const { return size() - tell(); }
blargg_err_t File_Reader::skip( long n ) blargg_err_t File_Reader::skip( long n )
{ {
assert( n >= 0 ); RETURN_VALIDITY_CHECK( n >= 0 );
if ( !n ) if ( !n )
return 0; return 0;
return seek( tell() + n ); return seek( tell() + n );
@ -67,13 +75,14 @@ Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
in = dr; in = dr;
remain_ = dr->remain(); remain_ = dr->remain();
if ( remain_ > size ) if ( remain_ > size )
remain_ = size; remain_ = max( 0l, size );
} }
long Subset_Reader::remain() const { return remain_; } long Subset_Reader::remain() const { return remain_; }
long Subset_Reader::read_avail( void* p, long s ) long Subset_Reader::read_avail( void* p, long s )
{ {
s = max( 0l, s );
if ( s > remain_ ) if ( s > remain_ )
s = remain_; s = remain_;
remain_ -= s; remain_ -= s;
@ -85,7 +94,7 @@ long Subset_Reader::read_avail( void* p, long s )
Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r ) Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
{ {
header = (char const*) h; header = (char const*) h;
header_end = header + size; header_end = header + max( 0l, size );
in = r; in = r;
} }
@ -93,6 +102,7 @@ long Remaining_Reader::remain() const { return header_end - header + in->remain(
long Remaining_Reader::read_first( void* out, long count ) long Remaining_Reader::read_first( void* out, long count )
{ {
count = max( 0l, count );
long first = header_end - header; long first = header_end - header;
if ( first ) if ( first )
{ {
@ -107,8 +117,9 @@ long Remaining_Reader::read_first( void* out, long count )
long Remaining_Reader::read_avail( void* out, long count ) long Remaining_Reader::read_avail( void* out, long count )
{ {
count = max( 0l, count );
long first = read_first( out, count ); long first = read_first( out, count );
long second = count - first; long second = max( 0l, count - first );
if ( second ) if ( second )
{ {
second = in->read_avail( (char*) out + first, second ); second = in->read_avail( (char*) out + first, second );
@ -120,8 +131,9 @@ long Remaining_Reader::read_avail( void* out, long count )
blargg_err_t Remaining_Reader::read( void* out, long count ) blargg_err_t Remaining_Reader::read( void* out, long count )
{ {
count = max( 0l, count );
long first = read_first( out, count ); long first = read_first( out, count );
long second = count - first; long second = max( 0l, count - first );
if ( !second ) if ( !second )
return 0; return 0;
return in->read( (char*) out + first, second ); return in->read( (char*) out + first, second );
@ -131,7 +143,7 @@ blargg_err_t Remaining_Reader::read( void* out, long count )
Mem_File_Reader::Mem_File_Reader( const void* p, long s ) : Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
begin( (const char*) p ), begin( (const char*) p ),
size_( s ) size_( max( 0l, s ) )
{ {
pos = 0; pos = 0;
} }
@ -141,6 +153,7 @@ long Mem_File_Reader::size() const { return size_; }
long Mem_File_Reader::read_avail( void* p, long s ) long Mem_File_Reader::read_avail( void* p, long s )
{ {
long r = remain(); long r = remain();
s = max( 0l, s );
if ( s > r ) if ( s > r )
s = r; s = r;
memcpy( p, begin + pos, s ); memcpy( p, begin + pos, s );
@ -152,6 +165,7 @@ long Mem_File_Reader::tell() const { return pos; }
blargg_err_t Mem_File_Reader::seek( long n ) blargg_err_t Mem_File_Reader::seek( long n )
{ {
RETURN_VALIDITY_CHECK( n >= 0 );
if ( n > size_ ) if ( n > size_ )
return eof_error; return eof_error;
pos = n; pos = n;
@ -164,7 +178,7 @@ Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
callback( c ), callback( c ),
data( d ) data( d )
{ {
remain_ = size; remain_ = max( 0l, size );
} }
long Callback_Reader::remain() const { return remain_; } long Callback_Reader::remain() const { return remain_; }
@ -173,13 +187,14 @@ long Callback_Reader::read_avail( void* out, long count )
{ {
if ( count > remain_ ) if ( count > remain_ )
count = remain_; count = remain_;
if ( Callback_Reader::read( out, count ) ) if ( count < 0 || Callback_Reader::read( out, count ) )
count = -1; count = -1;
return count; return count;
} }
blargg_err_t Callback_Reader::read( void* out, long count ) blargg_err_t Callback_Reader::read( void* out, long count )
{ {
RETURN_VALIDITY_CHECK( count >= 0 );
if ( count > remain_ ) if ( count > remain_ )
return eof_error; return eof_error;
return callback( data, out, count ); return callback( data, out, count );
@ -210,11 +225,12 @@ long Std_File_Reader::size() const
long Std_File_Reader::read_avail( void* p, long s ) long Std_File_Reader::read_avail( void* p, long s )
{ {
return fread( p, 1, s, (FILE*) file_ ); return fread( p, 1, max( 0l, s ), (FILE*) file_ );
} }
blargg_err_t Std_File_Reader::read( void* p, long s ) blargg_err_t Std_File_Reader::read( void* p, long s )
{ {
RETURN_VALIDITY_CHECK( s > 0 );
if ( s == (long) fread( p, 1, s, (FILE*) file_ ) ) if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
return 0; return 0;
if ( feof( (FILE*) file_ ) ) if ( feof( (FILE*) file_ ) )

View file

@ -129,6 +129,8 @@ private:
}; };
#ifdef HAVE_ZLIB_H #ifdef HAVE_ZLIB_H
#include <zlib.h>
// Gzip compressed file reader // Gzip compressed file reader
class Gzip_File_Reader : public File_Reader { class Gzip_File_Reader : public File_Reader {
public: public:
@ -143,7 +145,7 @@ public:
long tell() const; long tell() const;
blargg_err_t seek( long ); blargg_err_t seek( long );
private: private:
void* file_; gzFile file_;
long size_; long size_;
}; };
#endif #endif

View file

@ -178,6 +178,11 @@ blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo; return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
} }
long Music_Emu::tell_samples() const
{
return out_time;
}
long Music_Emu::tell() const long Music_Emu::tell() const
{ {
blargg_long rate = sample_rate() * stereo; blargg_long rate = sample_rate() * stereo;
@ -185,14 +190,18 @@ long Music_Emu::tell() const
return sec * 1000 + (out_time - sec * rate) * 1000 / rate; return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
} }
blargg_err_t Music_Emu::seek( long msec ) blargg_err_t Music_Emu::seek_samples( long time )
{ {
blargg_long time = msec_to_samples( msec );
if ( time < out_time ) if ( time < out_time )
RETURN_ERR( start_track( current_track_ ) ); RETURN_ERR( start_track( current_track_ ) );
return skip( time - out_time ); return skip( time - out_time );
} }
blargg_err_t Music_Emu::seek( long msec )
{
return seek_samples( msec_to_samples( msec ) );
}
blargg_err_t Music_Emu::skip( long count ) blargg_err_t Music_Emu::skip( long count )
{ {
require( current_track() >= 0 ); // start_track() must have been called already require( current_track() >= 0 ); // start_track() must have been called already

View file

@ -41,9 +41,15 @@ public:
// Number of milliseconds (1000 msec = 1 second) played since beginning of track // Number of milliseconds (1000 msec = 1 second) played since beginning of track
long tell() const; long tell() const;
// Number of samples generated since beginning of track
long tell_samples() const;
// Seek to new time in track. Seeking backwards or far forward can take a while. // Seek to new time in track. Seeking backwards or far forward can take a while.
blargg_err_t seek( long msec ); blargg_err_t seek( long msec );
// Equivalent to restarting track then skipping n samples
blargg_err_t seek_samples( long n );
// Skip n samples // Skip n samples
blargg_err_t skip( long n ); blargg_err_t skip( long n );

View file

@ -135,6 +135,9 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
blargg_long size = get_le32( block_header [0] ); blargg_long size = get_le32( block_header [0] );
blargg_long tag = get_le32( block_header [1] ); blargg_long tag = get_le32( block_header [1] );
if ( size <= 0 )
return "Corrupt file";
//debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) ); //debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
switch ( tag ) switch ( tag )

View file

@ -433,9 +433,7 @@ void Snes_Spc::cpu_write( int data, int addr, rel_time_t time )
#endif #endif
// Registers other than $F2 and $F4-$F7 // Registers other than $F2 and $F4-$F7
//if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 ) if ( reg != 2 && (reg < 4 || reg > 7) ) // 36%
// TODO: this is a bit on the fragile side
if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
cpu_write_smp_reg( data, time, reg ); cpu_write_smp_reg( data, time, reg );
} }
// High mem/address wrap-around // High mem/address wrap-around

View file

@ -76,8 +76,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
// TODO: remove non-wrapping versions? // TODO: remove non-wrapping versions?
#define SPC_NO_SP_WRAPAROUND 0 #define SPC_NO_SP_WRAPAROUND 0
#define SET_SP( v ) (sp = ram + 0x101 + (v)) #define SET_SP( v ) (sp = ram + 0x101 + ((uint8_t) v))
#define GET_SP() (sp - 0x101 - ram) #define GET_SP() (uint8_t (sp - 0x101 - ram))
#if SPC_NO_SP_WRAPAROUND #if SPC_NO_SP_WRAPAROUND
#define PUSH16( v ) (sp -= 2, SET_LE16( sp, v )) #define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
@ -485,7 +485,7 @@ loop:
case 0xAF: // MOV (X)+,A case 0xAF: // MOV (X)+,A
WRITE_DP( 0, x, a + no_read_before_write ); WRITE_DP( 0, x, a + no_read_before_write );
x++; x = (uint8_t) (x + 1);
goto loop; goto loop;
// 5. 8-BIT LOGIC OPERATION COMMANDS // 5. 8-BIT LOGIC OPERATION COMMANDS
@ -808,7 +808,7 @@ loop:
unsigned temp = y * a; unsigned temp = y * a;
a = (uint8_t) temp; a = (uint8_t) temp;
nz = ((temp >> 1) | temp) & 0x7F; nz = ((temp >> 1) | temp) & 0x7F;
y = temp >> 8; y = (uint8_t) (temp >> 8);
nz |= y; nz |= y;
goto loop; goto loop;
} }
@ -838,6 +838,7 @@ loop:
nz = (uint8_t) a; nz = (uint8_t) a;
a = (uint8_t) a; a = (uint8_t) a;
y = (uint8_t) y;
goto loop; goto loop;
} }
@ -1004,7 +1005,7 @@ loop:
case 0x7F: // RET1 case 0x7F: // RET1
temp = *sp; temp = *sp;
SET_PC( GET_LE16( sp + 1 ) ); SET_PC( GET_LE16( sp + 1 ) );
sp += 3; SET_SP( GET_SP() + 3 );
goto set_psw; goto set_psw;
case 0x8E: // POP PSW case 0x8E: // POP PSW
POP( temp ); POP( temp );

View file

@ -18,6 +18,19 @@ all other #include lines. */
#undef require #undef require
#define require( expr ) assert( expr ) #define require( expr ) assert( expr )
// Use to provide hints to compiler for optimized code layout in situations where we
// can almost always expect a conditional to go one way or the other. Should only be
// used in situations where an unexpected branch is truly exceptional though!
#undef likely
#undef unlikely
#ifdef __GNUC__
#define likely( x ) __builtin_expect(x, 1)
#define unlikely( x ) __builtin_expect(x, 0)
#else
#define likely( x ) (x)
#define unlikely( x ) (x)
#endif
// Like printf() except output goes to debug log file. Might be defined to do // Like printf() except output goes to debug log file. Might be defined to do
// nothing (not even evaluate its arguments). // nothing (not even evaluate its arguments).
// void debug_printf( const char* format, ... ); // void debug_printf( const char* format, ... );

View file

@ -337,7 +337,9 @@ BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p )
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); } BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); } BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); } BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
BLARGG_EXPORT int gme_tell_samples ( Music_Emu const* me ) { return me->tell_samples(); }
BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); } BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
BLARGG_EXPORT gme_err_t gme_seek_samples ( Music_Emu* me, int n ) { return me->seek_samples( n ); }
BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); } BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); } BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); } BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }

View file

@ -1,6 +1,6 @@
/* Game music emulator library C interface (also usable from C++) */ /* Game music emulator library C interface (also usable from C++) */
/* Game_Music_Emu 0.6.0 */ /* Game_Music_Emu 0.6.1 */
#ifndef GME_H #ifndef GME_H
#define GME_H #define GME_H
@ -8,7 +8,7 @@
extern "C" { extern "C" {
#endif #endif
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */ #define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
/* Error string returned by library functions, or NULL if no error (success) */ /* Error string returned by library functions, or NULL if no error (success) */
typedef const char* gme_err_t; typedef const char* gme_err_t;
@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
/* Number of milliseconds (1000 = one second) played since beginning of track */ /* Number of milliseconds (1000 = one second) played since beginning of track */
int gme_tell( Music_Emu const* ); int gme_tell( Music_Emu const* );
/* Number of samples generated since beginning of track */
int gme_tell_samples( Music_Emu const* );
/* Seek to new time in track. Seeking backwards or far forward can take a while. */ /* Seek to new time in track. Seeking backwards or far forward can take a while. */
gme_err_t gme_seek( Music_Emu*, int msec ); gme_err_t gme_seek( Music_Emu*, int msec );
/* Equivalent to restarting track then skipping n samples */
gme_err_t gme_seek_samples( Music_Emu*, int n );
/******** Informational ********/ /******** Informational ********/

View file

@ -3,7 +3,7 @@
# later are used by pkg-config. # later are used by pkg-config.
prefix=@CMAKE_INSTALL_PREFIX@ prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix} exec_prefix=${prefix}
lib_suffix= lib_suffix=@LIB_SUFFIX@
libdir=${exec_prefix}/lib${lib_suffix} libdir=${exec_prefix}/lib${lib_suffix}
includedir=${prefix}/include includedir=${prefix}/include
@ -13,3 +13,4 @@ URL: http://code.google.com/p/game-music-emu/
Version: @GME_VERSION@ Version: @GME_VERSION@
Cflags: -I${includedir} Cflags: -I${includedir}
Libs: -L${libdir} -lgme Libs: -L${libdir} -lgme
Libs.private: -lstdc++

View file

@ -1,6 +1,6 @@
/* Game music emulator library C interface (also usable from C++) */ /* Game music emulator library C interface (also usable from C++) */
/* Game_Music_Emu 0.6.0 */ /* Game_Music_Emu 0.6.1 */
#ifndef GME_H #ifndef GME_H
#define GME_H #define GME_H
@ -8,7 +8,7 @@
extern "C" { extern "C" {
#endif #endif
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */ #define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
/* Error string returned by library functions, or NULL if no error (success) */ /* Error string returned by library functions, or NULL if no error (success) */
typedef const char* gme_err_t; typedef const char* gme_err_t;
@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
/* Number of milliseconds (1000 = one second) played since beginning of track */ /* Number of milliseconds (1000 = one second) played since beginning of track */
int gme_tell( Music_Emu const* ); int gme_tell( Music_Emu const* );
/* Number of samples generated since beginning of track */
int gme_tell_samples( Music_Emu const* );
/* Seek to new time in track. Seeking backwards or far forward can take a while. */ /* Seek to new time in track. Seeking backwards or far forward can take a while. */
gme_err_t gme_seek( Music_Emu*, int msec ); gme_err_t gme_seek( Music_Emu*, int msec );
/* Equivalent to restarting track then skipping n samples */
gme_err_t gme_seek_samples( Music_Emu*, int n );
/******** Informational ********/ /******** Informational ********/

View file

@ -1,4 +1,4 @@
Game_Music_Emu 0.6.0: Game Music Emulators Game_Music_Emu 0.6.2: Game Music Emulators
------------------------------------------ ------------------------------------------
Game_Music_Emu is a collection of video game music file emulators that Game_Music_Emu is a collection of video game music file emulators that
support the following formats and systems: support the following formats and systems:
@ -34,30 +34,45 @@ several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
GP2X, and Nintendo DS. GP2X, and Nintendo DS.
Author : Shay Green <gblargg@gmail.com> Author : Shay Green <gblargg@gmail.com>
Website: http://www.slack.net/~ant/ Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
Forum : http://groups.google.com/group/blargg-sound-libs
License: GNU Lesser General Public License (LGPL) License: GNU Lesser General Public License (LGPL)
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
Getting Started Getting Started
--------------- ---------------
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
all source files in gme/. If you have CMake 2.6 or later, execute all source files in gme/.
run cmake Or, if you have CMake 2.6 or later, execute at a command prompt (from the
cd demo extracted source directory):
run make
Be sure "test.nsf" is in the same directory as the program. Running it mkdir build
cd build
cmake ../ # <-- Pass any needed CMake flags here
make # To build the library
cd demo
make # To build the demo itself
Be sure "test.nsf" is in the same directory as the demo program. Running it
should generate the recording "out.wav". should generate the recording "out.wav".
You can use "make install" to install the library. To choose where to install
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
(and replace /usr/local with the base path you wish to use). Alternately, you
can specify the base path to install to when you run "make install" by passing
'DESTDIR=/usr/local' on the make install command line (again, replace
/usr/local as appropriate).
To build a static library instead of shared (the default), pass
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
A slightly more extensive demo application is available in the player/ A slightly more extensive demo application is available in the player/
directory. It requires SDL to build. directory. It requires SDL to build.
Read gme.txt for more information. Post to the discussion forum for Read gme.txt for more information. Post to the discussion forum for
assistance. assistance.
Files Files
----- -----
gme.txt General notes about the library gme.txt General notes about the library

Binary file not shown.

Binary file not shown.