Commit 737ebcd0 authored by Libretro-Admin's avatar Libretro-Admin
Browse files

Add deps/game-music-emu

parent 66467b4c
[submodule "deps/game-music-emu"]
path = deps/game-music-emu
url = https://bitbucket.org/mpyne/game-music-emu.git
[submodule "deps/libretro-common"]
path = deps/libretro-common
url = https://github.com/libretro/libretro-common.git
game-music-emu @ 2cbb70f3
Subproject commit 2cbb70f3c27412db7e54ca65fa1a3fac3f6a7d64
# CMake project definition file.
project(libgme)
include (CheckCXXCompilerFlag)
# When version is changed, also change the one in gme/gme.h to match
set(GME_VERSION 0.6.1 CACHE INTERNAL "libgme Version")
# 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
# down the requirement, but I can't test that.
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
# Default emulators to build (all of them! ;)
if (NOT DEFINED USE_GME_AY)
SET(USE_GME_AY 1 CACHE BOOL "Enable support for Spectrum ZX music emulation")
endif()
if (NOT DEFINED USE_GME_GBS)
SET(USE_GME_GBS 1 CACHE BOOL "Enable support for Game Boy music emulation")
endif()
if (NOT DEFINED USE_GME_GYM)
SET(USE_GME_GYM 1 CACHE BOOL "Enable Sega MegaDrive/Genesis music emulation")
endif()
if (NOT DEFINED USE_GME_HES)
SET(USE_GME_HES 1 CACHE BOOL "Enable PC Engine/TurboGrafx-16 music emulation")
endif()
if (NOT DEFINED USE_GME_KSS)
SET(USE_GME_KSS 1 CACHE BOOL "Enable MSX or other Z80 systems music emulation")
endif()
if (NOT DEFINED USE_GME_NSF)
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation")
endif()
if (NOT DEFINED USE_GME_NSFE)
SET(USE_GME_NSFE 1 CACHE BOOL "Enable NES NSFE and NSF music emulation")
endif()
if (NOT DEFINED USE_GME_SAP)
SET(USE_GME_SAP 1 CACHE BOOL "Enable Atari SAP music emulation")
endif()
if (NOT DEFINED USE_GME_SPC)
SET(USE_GME_SPC 1 CACHE BOOL "Enable SNES SPC music emulation")
endif()
if (NOT DEFINED USE_GME_VGM)
SET(USE_GME_VGM 1 CACHE BOOL "Enable Sega VGM/VGZ music emulation")
endif()
if (USE_GME_NSFE AND NOT USE_GME_NSF)
MESSAGE(" -- NSFE support requires NSF, enabling NSF support. --")
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
endif()
option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
# Check for GCC "visibility" support.
if (CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
set (ENABLE_VISIBILITY OFF)
if (__LIBGME_TEST_VISIBILITY)
# get the gcc version
exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info)
string (REGEX MATCH "[3-9]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}")
# gcc <4.1 had poor support for symbol visibility
if ((${_gcc_version} VERSION_GREATER "4.1") OR (${_gcc_version} VERSION_EQUAL "4.1"))
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
set (ENABLE_VISIBILITY ON)
add_definitions (-DLIBGME_VISIBILITY)
# GCC >= 4.2 also correctly supports making inline members have hidden
# visibility by default.
if ((${_gcc_version} VERSION_GREATER "4.2") OR (${_gcc_version} VERSION_EQUAL "4.2"))
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
endif()
endif()
endif() # test visibility
# Cache this result
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
endif (CMAKE_COMPILER_IS_GNUCXX)
# Shared library defined here
add_subdirectory(gme)
# EXCLUDE_FROM_ALL adds build rules but keeps it out of default build
add_subdirectory(player EXCLUDE_FROM_ALL)
add_subdirectory(demo EXCLUDE_FROM_ALL)
Game_Music_Emu Change Log
-------------------------
Game_Music_Emu 0.6.1
--------------------
- Moved repository to Bitbucket since Google Code announced they would
shutdown this year.
- Packaging improvements:
- Honor $LIB_SUFFIX for installed pkg-config metadata.
- Support setting BUILD_SHARED_LIBS to OFF to build libgme as a static
library. (Pass -DBUILD_SHARED_LIBS=OFF when running cmake).
Thanks to lachs0r.
Game_Music_Emu 0.6.0
--------------------
- 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
# Rules for building the demo. Doesn't use an installed gme if you've already
# installed the project so if you're copying these rules you probably don't
# even need these next two lines if you're building against system-installed
# gme.
include_directories(${CMAKE_SOURCE_DIR}/gme ${CMAKE_SOURCE_DIR})
link_directories(${CMAKE_BINARY_DIR}/gme)
add_executable(demo Wave_Writer.cpp basics.c)
# Add command to copy build file over.
add_custom_command(TARGET demo
POST_BUILD
COMMAND cmake -E copy "${CMAKE_SOURCE_DIR}/test.nsf" ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Add convenience copy of test.nsf file for demo application"
VERBATIM) # VERBATIM is essentially required, "please use correct command line kthx"
target_link_libraries(demo gme)
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
#include "Wave_Writer.h"
#include <assert.h>
#include <stdlib.h>
/* Copyright (C) 2003-2006 by Shay Green. Permission is hereby granted, free
of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and
to permit persons to whom the Software is furnished to do so, subject to the
following conditions: The above copyright notice and this permission notice
shall be included in all copies or substantial portions of the Software. THE
SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
const int header_size = 0x2C;
static void exit_with_error( const char* str )
{
printf( "Error: %s\n", str ); getchar();
exit( EXIT_FAILURE );
}
Wave_Writer::Wave_Writer( long sample_rate, const char* filename )
{
sample_count_ = 0;
rate = sample_rate;
buf_pos = header_size;
chan_count = 1;
buf = (unsigned char*) malloc( buf_size * sizeof *buf );
if ( !buf )
exit_with_error( "Out of memory" );
file = fopen( filename, "wb" );
if ( !file )
exit_with_error( "Couldn't open WAVE file for writing" );
setvbuf( file, 0, _IOFBF, 32 * 1024L );
}
void Wave_Writer::flush()
{
if ( buf_pos && !fwrite( buf, buf_pos, 1, file ) )
exit_with_error( "Couldn't write WAVE data" );
buf_pos = 0;
}
void Wave_Writer::write( const sample_t* in, long remain, int skip )
{
sample_count_ += remain;
while ( remain )
{
if ( buf_pos >= buf_size )
flush();
long n = (buf_size - buf_pos) / sizeof (sample_t);
if ( n > remain )
n = remain;
remain -= n;
// convert to lsb first format
unsigned char* p = &buf [buf_pos];
while ( n-- )
{
int s = *in;
in += skip;
*p++ = (unsigned char) s;
*p++ = (unsigned char) (s >> 8);
}
buf_pos = p - buf;
assert( buf_pos <= buf_size );
}
}
void Wave_Writer::write( const float* in, long remain, int skip )
{
sample_count_ += remain;
while ( remain )
{
if ( buf_pos >= buf_size )
flush();
long n = (buf_size - buf_pos) / sizeof (sample_t);
if ( n > remain )
n = remain;
remain -= n;
// convert to lsb first format
unsigned char* p = &buf [buf_pos];
while ( n-- )
{
long s = (long) (*in * 0x7FFF);
in += skip;
if ( (short) s != s )
s = 0x7FFF - (s >> 24); // clamp to 16 bits
*p++ = (unsigned char) s;
*p++ = (unsigned char) (s >> 8);
}
buf_pos = p - buf;
assert( buf_pos <= buf_size );
}
}
void Wave_Writer::close()
{
if ( file )
{
flush();
// generate header
long ds = sample_count_ * sizeof (sample_t);
long rs = header_size - 8 + ds;
int frame_size = chan_count * sizeof (sample_t);
long bps = rate * frame_size;
unsigned char header [header_size] =
{
'R','I','F','F',
rs,rs>>8, // length of rest of file
rs>>16,rs>>24,
'W','A','V','E',
'f','m','t',' ',
0x10,0,0,0, // size of fmt chunk
1,0, // uncompressed format
chan_count,0, // channel count
rate,rate >> 8, // sample rate
rate>>16,rate>>24,
bps,bps>>8, // bytes per second
bps>>16,bps>>24,
frame_size,0, // bytes per sample frame
16,0, // bits per sample
'd','a','t','a',
ds,ds>>8,ds>>16,ds>>24// size of sample data
// ... // sample data
};
// write header
fseek( file, 0, SEEK_SET );
fwrite( header, sizeof header, 1, file );
fclose( file );
file = 0;
free( buf );
}
}
Wave_Writer::~Wave_Writer()
{
close();
}
// C interface
static Wave_Writer* ww;
void wave_open( long sample_rate, const char* filename )
{
ww = new Wave_Writer( sample_rate, filename );
assert( ww );
}
void wave_enable_stereo() { ww->enable_stereo(); }
long wave_sample_count() { return ww->sample_count(); }
void wave_write( const short* buf, long count ) { ww->write( buf, count ); }
void wave_close()
{
delete ww;
ww = 0;
}
/* WAVE sound file writer for recording 16-bit output during program development */
#ifndef WAVE_WRITER_H
#define WAVE_WRITER_H
#ifdef __cplusplus
extern "C" {
#endif
/* C interface */
void wave_open( long sample_rate, const char* filename );
void wave_enable_stereo( void );
void wave_write( const short* buf, long count );
long wave_sample_count( void );
void wave_close( void );
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#include <stddef.h>
#include <stdio.h>
/* C++ interface */
class Wave_Writer {
public:
typedef short sample_t;
// Create sound file with given sample rate (in Hz) and filename.
// Exits program if there's an error.
Wave_Writer( long sample_rate, char const* filename = "out.wav" );
// Enable stereo output
void enable_stereo();
// Append 'count' samples to file. Use every 'skip'th source sample; allows
// one channel of stereo sample pairs to be written by specifying a skip of 2.
void write( const sample_t*, long count, int skip = 1 );
// Append 'count' floating-point samples to file. Use every 'skip'th source sample;
// allows one channel of stereo sample pairs to be written by specifying a skip of 2.
void write( const float*, long count, int skip = 1 );
// Number of samples written so far
long sample_count() const;