diff options
author | 2009-08-16 20:42:17 +0200 | |
---|---|---|
committer | 2009-08-16 20:51:54 +0200 | |
commit | 1e7c5ae1fa743a73fbc0c1831201271691c6ae95 (patch) | |
tree | fa24c03544ba4066d57f288d91b6e3df9d80c4fd /gme/Game_Music_Emu-0.5.2/demo | |
parent | 36df76395c9e7af90bfe5bfb8c717de7a552847a (diff) |
fixed gme source distribution
Diffstat (limited to 'gme/Game_Music_Emu-0.5.2/demo')
-rw-r--r-- | gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.cpp | 182 | ||||
-rw-r--r-- | gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.h | 73 | ||||
-rw-r--r-- | gme/Game_Music_Emu-0.5.2/demo/basics.c | 57 | ||||
-rw-r--r-- | gme/Game_Music_Emu-0.5.2/demo/cpp_basics.cpp | 67 | ||||
-rw-r--r-- | gme/Game_Music_Emu-0.5.2/demo/features.c | 149 |
5 files changed, 528 insertions, 0 deletions
diff --git a/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.cpp b/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.cpp new file mode 100644 index 00000000..ec40959d --- /dev/null +++ b/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.cpp @@ -0,0 +1,182 @@ +// Game_Music_Emu 0.5.2. 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; +} diff --git a/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.h b/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.h new file mode 100644 index 00000000..da08cc2a --- /dev/null +++ b/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.h @@ -0,0 +1,73 @@ +/* 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; + + // Finish writing sound file and close it + void close(); + + ~Wave_Writer(); +public: + // Deprecated + void stereo( bool b ) { chan_count = b ? 2 : 1; } +private: + enum { buf_size = 32768 * 2 }; + unsigned char* buf; + FILE* file; + long sample_count_; + long rate; + long buf_pos; + int chan_count; + + void flush(); +}; + +inline void Wave_Writer::enable_stereo() { chan_count = 2; } + +inline long Wave_Writer::sample_count() const { return sample_count_; } + +#endif + +#endif diff --git a/gme/Game_Music_Emu-0.5.2/demo/basics.c b/gme/Game_Music_Emu-0.5.2/demo/basics.c new file mode 100644 index 00000000..55178251 --- /dev/null +++ b/gme/Game_Music_Emu-0.5.2/demo/basics.c @@ -0,0 +1,57 @@ +/* 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 "Wave_Writer.h" /* wave_ functions for writing sound file */ +#include <stdlib.h> +#include <stdio.h> + +void handle_error( const char* str ); + +int main() +{ + long sample_rate = 44100; /* number of samples per second */ + int track = 0; /* index of track to play (0 = first) */ + + /* Open music file in new emulator */ + Music_Emu* emu; + handle_error( gme_open_file( filename, &emu, sample_rate ) ); + + /* Start track */ + handle_error( gme_start_track( emu, track ) ); + + /* Begin writing to wave file */ + wave_open( sample_rate, "out.wav" ); + wave_enable_stereo(); + + /* Record 10 seconds of track */ + while ( gme_tell( emu ) < 10 * 1000L ) + { + /* Sample buffer */ + #define buf_size 1024 /* can be any multiple of 2 */ + short buf [buf_size]; + + /* Fill sample buffer */ + handle_error( gme_play( emu, buf_size, buf ) ); + + /* Write samples to wave file */ + wave_write( buf, buf_size ); + } + + /* Cleanup */ + gme_delete( emu ); + wave_close(); + + return 0; +} + +void handle_error( const char* str ) +{ + if ( str ) + { + printf( "Error: %s\n", str ); getchar(); + exit( EXIT_FAILURE ); + } +} diff --git a/gme/Game_Music_Emu-0.5.2/demo/cpp_basics.cpp b/gme/Game_Music_Emu-0.5.2/demo/cpp_basics.cpp new file mode 100644 index 00000000..53fab418 --- /dev/null +++ b/gme/Game_Music_Emu-0.5.2/demo/cpp_basics.cpp @@ -0,0 +1,67 @@ +// 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 "Wave_Writer.h" +#include <stdlib.h> +#include <stdio.h> + +void handle_error( const char* str ); + +int main() +{ + long sample_rate = 44100; // number of samples per second + int track = 0; // index of track to play (0 = first) + + // Determine file type + gme_type_t file_type; + handle_error( gme_identify_file( filename, &file_type ) ); + if ( !file_type ) + handle_error( "Unsupported music type" ); + + // Create emulator and set sample rate + Music_Emu* emu = file_type->new_emu(); + if ( !emu ) + handle_error( "Out of memory" ); + handle_error( emu->set_sample_rate( sample_rate ) ); + + // Load music file into emulator + handle_error( emu->load_file( filename ) ); + + // Start track + handle_error( emu->start_track( track ) ); + + // Begin writing to wave file + Wave_Writer wave( sample_rate, "out.wav" ); + wave.enable_stereo(); + + // Record 10 seconds of track + while ( emu->tell() < 10 * 1000L ) + { + // Sample buffer + const long size = 1024; // can be any multiple of 2 + short buf [size]; + + // Fill buffer + handle_error( emu->play( size, buf ) ); + + // Write samples to wave file + wave.write( buf, size ); + } + + // Cleanup + delete emu; + + return 0; +} + +void handle_error( const char* str ) +{ + if ( str ) + { + printf( "Error: %s\n", str ); getchar(); + exit( EXIT_FAILURE ); + } +} diff --git a/gme/Game_Music_Emu-0.5.2/demo/features.c b/gme/Game_Music_Emu-0.5.2/demo/features.c new file mode 100644 index 00000000..96a9a8a9 --- /dev/null +++ b/gme/Game_Music_Emu-0.5.2/demo/features.c @@ -0,0 +1,149 @@ +/* C example that opens any music file type, opens an m3u playlist if present, +prints its info and voice names, customizes the sound, and fades a track out. +Records to "out.wav". */ + +static char filename [] = "test.nsf"; /* opens this file (can be any music type) */ +static char playlist [] = "test.m3u"; /* uses this playlist, if present*/ + +#include "gme/gme.h" + +#include "Wave_Writer.h" /* wave_ functions for writing sound file */ +#include <stdlib.h> +#include <stdio.h> + +void handle_error( const char* ); + +/* Example of loading from memory, which would be useful if using a zip file or +other custom format. In this example it's silly because we could just use +gme_load( &emu, sample_rate, path, 0 ). */ +Music_Emu* load_file( const char* path, long sample_rate ) +{ + Music_Emu* emu; + char* data; + long size; + + /* Read file data into memory. You might read the data from a zip file or + other compressed format. */ + FILE* in = fopen( path, "rb" ); + if ( !in ) + handle_error( "Couldn't open file" ); + fseek( in, 0, SEEK_END ); + size = ftell( in ); + rewind( in ); + + data = malloc( size ); + if ( !data ) + handle_error( "Out of memory" ); + if ( fread( data, size, 1, in ) <= 0 ) + handle_error( "Read error" ); + fclose( in ); + + handle_error( gme_open_data( data, size, &emu, sample_rate ) ); + free( data ); /* a copy is made of the data */ + return emu; +} + +/* Print any warning for most recent emulator action (load, start_track, play) */ +void print_warning( Music_Emu* emu ) +{ + const char* warning = gme_warning( emu ); + if ( warning ) + printf( "**** Warning: %s\n\n", warning ); +} + +static char my_data [] = "Our cleanup function was called"; + +/* Example cleanup function automatically called when emulator is deleted. */ +static void my_cleanup( void* my_data ) +{ + printf( "\n%s\n", (char*) my_data ); +} + +int main() +{ + long sample_rate = 44100; + int track = 0; /* index of track to play (0 = first) */ + int i; + + /* Load file into emulator */ + Music_Emu* emu = load_file( filename, sample_rate ); + print_warning( emu ); + + /* Register cleanup function and confirmation string as data */ + gme_set_user_data( emu, my_data ); + gme_set_user_cleanup( emu, my_cleanup ); + + /* Load .m3u playlist file. All tracks are assumed to use current file. + We ignore error here in case there is no m3u file present. */ + gme_load_m3u( emu, playlist ); + print_warning( emu ); + + /* Get and print main info for track */ + { + track_info_t info; + handle_error( gme_track_info( emu, &info, track ) ); + printf( "System : %s\n", info.system ); + printf( "Game : %s\n", info.game ); + printf( "Author : %s\n", info.author ); + printf( "Copyright: %s\n", info.copyright ); + printf( "Comment : %s\n", info.comment ); + printf( "Dumper : %s\n", info.dumper ); + printf( "Tracks : %d\n", (int) info.track_count ); + printf( "\n" ); + printf( "Track : %d\n", (int) track + 1 ); + printf( "Name : %s\n", info.song ); + printf( "Length : %ld:%02ld", + (long) info.length / 1000 / 60, (long) info.length / 1000 % 60 ); + if ( info.loop_length != 0 ) + printf( " (endless)" ); + printf( "\n\n" ); + } + + /* Print voice names */ + for ( i = 0; i < gme_voice_count( emu ); i++ ) + printf( "Voice %d: %s\n", i, gme_voice_names( emu ) [i] ); + + /* Add some stereo enhancement */ + gme_set_stereo_depth( emu, 0.20 ); + + /* Adjust equalizer for crisp, bassy sound */ + { + gme_equalizer_t eq; + eq.treble = 0.0; + eq.bass = 20; + gme_set_equalizer( emu, &eq ); + } + + /* Start track and begin fade at 10 seconds */ + handle_error( gme_start_track( emu, track ) ); + print_warning( emu ); + gme_set_fade( emu, 10 * 1000L ); + + /* Record track until it ends */ + wave_open( sample_rate, "out.wav" ); + wave_enable_stereo(); + while ( !gme_track_ended( emu ) ) + { + #define buf_size 1024 + short buf [buf_size]; + handle_error( gme_play( emu, buf_size, buf ) ); + print_warning( emu ); + wave_write( buf, buf_size ); + } + + /* Cleanup */ + gme_delete( emu ); + wave_close(); + + getchar(); + return 0; +} + +void handle_error( const char* str ) +{ + if ( str ) + { + printf( "Error: %s\n", str ); getchar(); + exit( EXIT_FAILURE ); + } +} |