diff options
author | James Cowgill <jcowgill@debian.org> | 2018-12-23 22:09:29 +0000 |
---|---|---|
committer | James Cowgill <jcowgill@debian.org> | 2018-12-23 22:09:29 +0000 |
commit | fa977e826b34fe2fcfeb253f50d8def6127068b6 (patch) | |
tree | d0e1cd7cdc903a5c858d2339ec4a359c6b7a9903 /openmpt123 | |
parent | db8e0c1070c79653be541929205e7b7004d43663 (diff) |
New upstream version 0.4.0
Diffstat (limited to 'openmpt123')
-rw-r--r-- | openmpt123/openmpt123.cpp | 122 | ||||
-rw-r--r-- | openmpt123/openmpt123.hpp | 183 | ||||
-rw-r--r-- | openmpt123/openmpt123_allegro42.hpp | 176 | ||||
-rw-r--r-- | openmpt123/openmpt123_flac.hpp | 6 | ||||
-rw-r--r-- | openmpt123/openmpt123_mmio.hpp | 4 | ||||
-rw-r--r-- | openmpt123/openmpt123_portaudio.hpp | 10 | ||||
-rw-r--r-- | openmpt123/openmpt123_pulseaudio.hpp | 10 | ||||
-rw-r--r-- | openmpt123/openmpt123_raw.hpp | 6 | ||||
-rw-r--r-- | openmpt123/openmpt123_sdl.hpp | 10 | ||||
-rw-r--r-- | openmpt123/openmpt123_sdl2.hpp | 10 | ||||
-rw-r--r-- | openmpt123/openmpt123_sndfile.hpp | 6 | ||||
-rw-r--r-- | openmpt123/openmpt123_stdout.hpp | 4 | ||||
-rw-r--r-- | openmpt123/openmpt123_waveout.hpp | 10 |
13 files changed, 443 insertions, 114 deletions
diff --git a/openmpt123/openmpt123.cpp b/openmpt123/openmpt123.cpp index 4db2dae..3e4a646 100644 --- a/openmpt123/openmpt123.cpp +++ b/openmpt123/openmpt123.cpp @@ -8,8 +8,6 @@ */ static const char * const license = -"The OpenMPT code is licensed under the BSD license." "\n" -"" "\n" "Copyright (c) 2004-2018, OpenMPT contributors" "\n" "Copyright (c) 1997-2003, Olivier Lapicque" "\n" "All rights reserved." "\n" @@ -60,7 +58,15 @@ static const char * const license = #include <cstring> #include <ctime> -#if defined(WIN32) +#if defined(__DJGPP__) +#include <conio.h> +#include <fcntl.h> +#include <io.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <termios.h> +#include <unistd.h> +#elif defined(WIN32) #include <conio.h> #include <fcntl.h> #include <io.h> @@ -90,6 +96,7 @@ static const char * const license = #include "openmpt123_sndfile.hpp" #include "openmpt123_raw.hpp" #include "openmpt123_stdout.hpp" +#include "openmpt123_allegro42.hpp" #include "openmpt123_portaudio.hpp" #include "openmpt123_pulseaudio.hpp" #include "openmpt123_sdl.hpp" @@ -99,35 +106,27 @@ static const char * const license = namespace openmpt123 { struct silent_exit_exception : public std::exception { - silent_exit_exception() { } }; struct show_license_exception : public std::exception { - show_license_exception() { } }; struct show_credits_exception : public std::exception { - show_credits_exception() { } }; struct show_man_version_exception : public std::exception { - show_man_version_exception() { } }; struct show_man_help_exception : public std::exception { - show_man_help_exception() { } }; struct show_short_version_number_exception : public std::exception { - show_short_version_number_exception() { } }; struct show_version_number_exception : public std::exception { - show_version_number_exception() { } }; struct show_long_version_number_exception : public std::exception { - show_long_version_number_exception() { } }; bool IsTerminal( int fd ) { @@ -205,27 +204,27 @@ public: impl = 0; } } - virtual void write_metadata( std::map<std::string,std::string> metadata ) { + void write_metadata( std::map<std::string,std::string> metadata ) override { impl->write_metadata( metadata ); } - virtual void write_updated_metadata( std::map<std::string,std::string> metadata ) { + void write_updated_metadata( std::map<std::string,std::string> metadata ) override { impl->write_updated_metadata( metadata ); } - virtual void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { impl->write( buffers, frames ); } - virtual void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { impl->write( buffers, frames ); } }; static std::string ctls_to_string( const std::map<std::string, std::string> & ctls ) { std::string result; - for ( std::map<std::string, std::string>::const_iterator it = ctls.begin(); it != ctls.end(); ++it ) { + for ( const auto & ctl : ctls ) { if ( !result.empty() ) { result += "; "; } - result += it->first + "=" + it->second; + result += ctl.first + "=" + ctl.second; } return result; } @@ -286,8 +285,8 @@ static std::ostream & operator << ( std::ostream & s, const commandlineflags & f s << "Ctls: " << ctls_to_string( flags.ctls ) << std::endl; s << std::endl; s << "Files: " << std::endl; - for ( std::vector<std::string>::const_iterator filename = flags.filenames.begin(); filename != flags.filenames.end(); ++filename ) { - s << " " << *filename << std::endl; + for ( const auto & filename : flags.filenames ) { + s << " " << filename << std::endl; } s << std::endl; return s; @@ -469,13 +468,13 @@ static void show_info( std::ostream & log, bool verbose ) { fields.push_back( field ); } bool first = true; - for ( std::vector<std::string>::const_iterator it = fields.begin(); it != fields.end(); ++it ) { + for ( const auto & field : fields ) { if ( first ) { first = false; } else { log << ", "; } - log << (*it); + log << field; } } log << std::endl; @@ -666,13 +665,13 @@ static void show_help( textout & log, bool with_info = true, bool longhelp = fal log << " "; std::vector<std::string> extensions = openmpt::get_supported_extensions(); bool first = true; - for ( std::vector<std::string>::iterator i = extensions.begin(); i != extensions.end(); ++i ) { + for ( const auto & extension : extensions ) { if ( first ) { first = false; } else { log << ", "; } - log << *i; + log << extension; } log << std::endl; } @@ -741,15 +740,15 @@ void ctl_set( Tmod & mod, const std::string & ctl, const T & val ) { template < typename Tmod > static void apply_mod_settings( commandlineflags & flags, Tmod & mod ) { - flags.separation = std::max( flags.separation, 0 ); - flags.filtertaps = std::max( flags.filtertaps, 1 ); - flags.filtertaps = std::min( flags.filtertaps, 8 ); - flags.ramping = std::max( flags.ramping, -1 ); - flags.ramping = std::min( flags.ramping, 10 ); - flags.tempo = std::max( flags.tempo, -48 ); - flags.tempo = std::min( flags.tempo, 48 ); - flags.pitch = std::max( flags.pitch, -48 ); - flags.pitch = std::min( flags.pitch, 48 ); + flags.separation = std::max( flags.separation, std::int32_t( 0 ) ); + flags.filtertaps = std::max( flags.filtertaps, std::int32_t( 1 ) ); + flags.filtertaps = std::min( flags.filtertaps, std::int32_t( 8 ) ); + flags.ramping = std::max( flags.ramping, std::int32_t( -1 ) ); + flags.ramping = std::min( flags.ramping, std::int32_t( 10 ) ); + flags.tempo = std::max( flags.tempo, std::int32_t( -48 ) ); + flags.tempo = std::min( flags.tempo, std::int32_t( 48 ) ); + flags.pitch = std::max( flags.pitch, std::int32_t( -48 ) ); + flags.pitch = std::min( flags.pitch, std::int32_t( 48 ) ); mod.set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, flags.gain ); mod.set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, flags.separation ); mod.set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, flags.filtertaps ); @@ -1125,7 +1124,16 @@ void render_loop( commandlineflags & flags, Tmod & mod, double & duration, texto if ( flags.mode == ModeUI ) { -#if defined( WIN32 ) +#if defined( __DJGPP__ ) + + while ( kbhit() ) { + int c = getch(); + if ( !handle_keypress( c, flags, mod, audio_stream ) ) { + return; + } + } + +#elif defined( WIN32 ) while ( _kbhit() ) { int c = _getch(); @@ -1401,8 +1409,8 @@ template < typename Tmod > std::map<std::string,std::string> get_metadata( const Tmod & mod ) { std::map<std::string,std::string> result; const std::vector<std::string> metadata_keys = mod.get_metadata_keys(); - for ( std::vector<std::string>::const_iterator key = metadata_keys.begin(); key != metadata_keys.end(); ++key ) { - result[ *key ] = mod.get_metadata( *key ); + for ( const auto & key : metadata_keys ) { + result[ key ] = mod.get_metadata( key ); } return result; } @@ -1426,9 +1434,9 @@ public: static void show_fields( textout & log, const std::vector<field> & fields ) { const std::size_t fw = 11; - for ( std::vector<field>::const_iterator it = fields.begin(); it != fields.end(); ++it ) { - std::string key = it->key; - std::string val = it->val; + for ( const auto & field :fields ) { + std::string key = field.key; + std::string val = field.val; if ( key.length() < fw ) { key += std::string( fw - key.length(), '.' ); } @@ -1534,6 +1542,9 @@ void render_mod_file( commandlineflags & flags, const std::string & filename, st set_field( fields, "Container" ).ostream() << mod.get_metadata( "container" ) << " (" << mod.get_metadata( "container_long" ) << ")"; } set_field( fields, "Type" ).ostream() << mod.get_metadata( "type" ) << " (" << mod.get_metadata( "type_long" ) << ")"; + if ( !mod.get_metadata( "originaltype" ).empty() ) { + set_field( fields, "Orig. Type" ).ostream() << mod.get_metadata( "originaltype" ) << " (" << mod.get_metadata( "originaltype_long" ) << ")"; + } if ( ( mod.get_num_subsongs() > 1 ) && ( flags.subsong != -1 ) ) { set_field( fields, "Subsong" ).ostream() << flags.subsong; } @@ -1968,7 +1979,9 @@ static commandlineflags parse_openmpt123( const std::vector<std::string> & args, commandlineflags flags; bool files_only = false; - for ( std::vector<std::string>::const_iterator i = args.begin(); i != args.end(); ++i ) { + // cppcheck false-positive + // cppcheck-suppress StlMissingComparison + for ( auto i = args.begin(); i != args.end(); ++i ) { if ( i == args.begin() ) { // skip program name continue; @@ -2068,6 +2081,9 @@ static commandlineflags parse_openmpt123( const std::vector<std::string> & args, #if defined( WIN32 ) drivers << " " << "waveout" << std::endl; #endif +#if defined( MPT_WITH_ALLEGRO42 ) + drivers << " " << "allegro42" << std::endl; +#endif throw show_help_exception( drivers.str() ); } else if ( nextarg == "default" ) { flags.driver = ""; @@ -2094,6 +2110,9 @@ static commandlineflags parse_openmpt123( const std::vector<std::string> & args, #if defined( WIN32 ) devices << show_waveout_devices( log ); #endif +#if defined( MPT_WITH_ALLEGRO42 ) + devices << show_allegro42_devices( log ); +#endif throw show_help_exception( devices.str() ); } else if ( nextarg == "default" ) { flags.device = ""; @@ -2354,8 +2373,8 @@ static int main( int argc, char * argv [] ) { try { bool stdin_can_ui = true; - for ( std::vector<std::string>::iterator filename = flags.filenames.begin(); filename != flags.filenames.end(); ++filename ) { - if ( *filename == "-" ) { + for ( const auto & filename : flags.filenames ) { + if ( filename == "-" ) { stdin_can_ui = false; break; } @@ -2406,8 +2425,8 @@ static int main( int argc, char * argv [] ) { switch ( flags.mode ) { case ModeProbe: { - for ( std::vector<std::string>::iterator filename = flags.filenames.begin(); filename != flags.filenames.end(); ++filename ) { - probe_file( flags, *filename, log ); + for ( const auto & filename : flags.filenames ) { + probe_file( flags, filename, log ); flags.playlist_index++; } } break; @@ -2450,6 +2469,11 @@ static int main( int argc, char * argv [] ) { waveout_stream_raii waveout_stream( flags ); render_files( flags, log, waveout_stream, prng ); #endif +#if defined( MPT_WITH_ALLEGRO42 ) + } else if ( flags.driver == "allegro42" || flags.driver.empty() ) { + allegro42_stream_raii allegro42_stream( flags, log ); + render_files( flags, log, allegro42_stream, prng ); +#endif } else { if ( flags.driver.empty() ) { throw exception( "openmpt123 is compiled without any audio driver" ); @@ -2459,10 +2483,10 @@ static int main( int argc, char * argv [] ) { } } break; case ModeRender: { - for ( std::vector<std::string>::iterator filename = flags.filenames.begin(); filename != flags.filenames.end(); ++filename ) { + for ( const auto & filename : flags.filenames ) { flags.apply_default_buffer_sizes(); - file_audio_stream_raii file_audio_stream( flags, *filename + std::string(".") + flags.output_extension, log ); - render_file( flags, *filename, log, file_audio_stream ); + file_audio_stream_raii file_audio_stream( flags, filename + std::string(".") + flags.output_extension, log ); + render_file( flags, filename, log, file_audio_stream ); flags.playlist_index++; } } break; @@ -2473,6 +2497,12 @@ static int main( int argc, char * argv [] ) { } catch ( args_error_exception & ) { show_help( std_out ); return 1; +#ifdef MPT_WITH_ALLEGRO42 + } catch ( allegro42_exception & e ) { + std_err << "Allegro-4.2 error: " << e.what() << std::endl; + std_err.writeout(); + return 1; +#endif #ifdef MPT_WITH_PULSEAUDIO } catch ( pulseaudio_exception & e ) { std_err << "PulseAudio error: " << e.what() << std::endl; diff --git a/openmpt123/openmpt123.hpp b/openmpt123/openmpt123.hpp index 4665685..89104c9 100644 --- a/openmpt123/openmpt123.hpp +++ b/openmpt123/openmpt123.hpp @@ -145,7 +145,7 @@ public: return; } public: - virtual void write( const std::string & /* text */ ) { + void write( const std::string & /* text */ ) override { return; } }; @@ -163,10 +163,10 @@ public: writeout(); } public: - virtual void write( const std::string & text ) { + void write( const std::string & text ) override { s << text; } - virtual void writeout() { + void writeout() override { textout::writeout(); s.flush(); } @@ -187,7 +187,7 @@ public: writeout(); } public: - virtual void write( const std::string & text ) { + void write( const std::string & text ) override { #if defined(UNICODE) std::wstring wtext = utf8_to_wstring( text ); WriteConsole( handle, wtext.data(), static_cast<DWORD>( wtext.size() ), NULL, NULL ); @@ -328,9 +328,15 @@ struct commandlineflags { device = ""; buffer = default_high; period = default_high; +#if defined(__DJGPP__) + samplerate = 44100; + channels = 2; + use_float = false; +#else samplerate = 48000; channels = 2; use_float = true; +#endif gain = 0; separation = 100; filtertaps = 8; @@ -344,8 +350,13 @@ struct commandlineflags { end_time = 0.0; quiet = false; verbose = false; +#if defined(__DJGPP__) + terminal_width = 80; + terminal_height = 25; +#else terminal_width = 72; terminal_height = 23; +#endif #if defined(WIN32) CONSOLE_SCREEN_BUFFER_INFO csbi; ZeroMemory( &csbi, sizeof( CONSOLE_SCREEN_BUFFER_INFO ) ); @@ -404,7 +415,7 @@ struct commandlineflags { shuffle = false; restart = false; playlist_index = 0; - output_extension = "wav"; + output_extension = "auto"; force_overwrite = false; paused = false; } @@ -418,8 +429,8 @@ struct commandlineflags { if ( !output_filename.empty() && ( device != commandlineflags().device || use_stdout ) ) { throw args_error_exception(); } - for ( std::vector<std::string>::iterator i = filenames.begin(); i != filenames.end(); ++i ) { - if ( *i == "-" ) { + for ( const auto & filename : filenames ) { + if ( filename == "-" ) { canUI = false; } } @@ -485,21 +496,20 @@ struct commandlineflags { if ( samplerate < 0 ) { samplerate = commandlineflags().samplerate; } - if ( mode == ModeRender && !output_filename.empty() ) { - std::ostringstream warning; - warning << "Warning: --output is deprecated in --render mode. Use --output-type instead." << std::endl; - warnings += warning.str(); + if ( output_extension == "auto" ) { + output_extension = ""; } - if ( mode != ModeRender && output_extension != "wav" ) { - std::ostringstream warning; - warning << "Warning: --output-type is deprecated in modes other than --render. Use --output instead." << std::endl; - warnings += warning.str(); + if ( mode != ModeRender && !output_extension.empty() ) { + throw args_error_exception(); + } + if ( mode == ModeRender && !output_filename.empty() ) { + throw args_error_exception(); } - if ( !output_filename.empty() ) { + if ( mode != ModeRender && !output_filename.empty() ) { output_extension = get_extension( output_filename ); } - if ( mode == ModeRender && output_extension.empty() ) { - throw args_error_exception(); + if ( output_extension.empty() ) { + output_extension = "wav"; } } }; @@ -510,8 +520,8 @@ template < > float convert_sample_to( float val ) { } template < > std::int16_t convert_sample_to( float val ) { std::int32_t tmp = static_cast<std::int32_t>( val * 32768.0f ); - tmp = std::min( tmp, 32767 ); - tmp = std::max( tmp, -32768 ); + tmp = std::min( tmp, std::int32_t( 32767 ) ); + tmp = std::max( tmp, std::int32_t( -32768 ) ); return static_cast<std::int16_t>( tmp ); } @@ -591,7 +601,7 @@ private: } } public: - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { lock(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { @@ -601,7 +611,7 @@ public: } unlock(); } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { lock(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { @@ -613,7 +623,120 @@ public: } virtual void lock() = 0; virtual void unlock() = 0; - virtual bool sleep( int ms ) = 0; + bool sleep( int ms ) override = 0; +}; + +class write_buffers_polling_wrapper : public write_buffers_interface { +protected: + std::size_t channels; + std::size_t sampleQueueMaxFrames; + std::deque<float> sampleQueue; +protected: + virtual ~write_buffers_polling_wrapper() { + return; + } +protected: + write_buffers_polling_wrapper( const commandlineflags & flags ) + : channels(flags.channels) + , sampleQueueMaxFrames(0) + { + return; + } + void set_queue_size_frames( std::size_t frames ) { + sampleQueueMaxFrames = frames; + } + template < typename Tsample > + Tsample pop_queue() { + float val = 0.0f; + if ( !sampleQueue.empty() ) { + val = sampleQueue.front(); + sampleQueue.pop_front(); + } + return convert_sample_to<Tsample>( val ); + } +public: + void write( const std::vector<float*> buffers, std::size_t frames ) override { + for ( std::size_t frame = 0; frame < frames; ++frame ) { + for ( std::size_t channel = 0; channel < channels; ++channel ) { + sampleQueue.push_back( buffers[channel][frame] ); + } + while ( sampleQueue.size() >= sampleQueueMaxFrames * channels ) { + while ( !forward_queue() ) { + sleep( 1 ); + } + } + } + } + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { + for ( std::size_t frame = 0; frame < frames; ++frame ) { + for ( std::size_t channel = 0; channel < channels; ++channel ) { + sampleQueue.push_back( buffers[channel][frame] * (1.0f/32768.0f) ); + } + while ( sampleQueue.size() >= sampleQueueMaxFrames * channels ) { + while ( !forward_queue() ) { + sleep( 1 ); + } + } + } + } + virtual bool forward_queue() = 0; + bool sleep( int ms ) override = 0; +}; + +class write_buffers_polling_wrapper_int : public write_buffers_interface { +protected: + std::size_t channels; + std::size_t sampleQueueMaxFrames; + std::deque<std::int16_t> sampleQueue; +protected: + virtual ~write_buffers_polling_wrapper_int() { + return; + } +protected: + write_buffers_polling_wrapper_int( const commandlineflags & flags ) + : channels(flags.channels) + , sampleQueueMaxFrames(0) + { + return; + } + void set_queue_size_frames( std::size_t frames ) { + sampleQueueMaxFrames = frames; + } + std::int16_t pop_queue() { + std::int16_t val = 0; + if ( !sampleQueue.empty() ) { + val = sampleQueue.front(); + sampleQueue.pop_front(); + } + return val; + } +public: + void write( const std::vector<float*> buffers, std::size_t frames ) override { + for ( std::size_t frame = 0; frame < frames; ++frame ) { + for ( std::size_t channel = 0; channel < channels; ++channel ) { + sampleQueue.push_back( convert_sample_to<std::int16_t>( buffers[channel][frame] ) ); + } + while ( sampleQueue.size() >= sampleQueueMaxFrames * channels ) { + while ( !forward_queue() ) { + sleep( 1 ); + } + } + } + } + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { + for ( std::size_t frame = 0; frame < frames; ++frame ) { + for ( std::size_t channel = 0; channel < channels; ++channel ) { + sampleQueue.push_back( buffers[channel][frame] ); + } + while ( sampleQueue.size() >= sampleQueueMaxFrames * channels ) { + while ( !forward_queue() ) { + sleep( 1 ); + } + } + } + } + virtual bool forward_queue() = 0; + bool sleep( int ms ) override = 0; }; class void_audio_stream : public write_buffers_interface { @@ -622,15 +745,15 @@ public: return; } public: - virtual void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { (void)buffers; (void)frames; } - virtual void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { (void)buffers; (void)frames; } - virtual bool is_dummy() const { + bool is_dummy() const override { return true; } }; @@ -641,16 +764,16 @@ protected: return; } public: - virtual void write_metadata( std::map<std::string,std::string> metadata ) { + void write_metadata( std::map<std::string,std::string> metadata ) override { (void)metadata; return; } - virtual void write_updated_metadata( std::map<std::string,std::string> metadata ) { + void write_updated_metadata( std::map<std::string,std::string> metadata ) override { (void)metadata; return; } - virtual void write( const std::vector<float*> buffers, std::size_t frames ) = 0; - virtual void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) = 0; + void write( const std::vector<float*> buffers, std::size_t frames ) override = 0; + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override = 0; virtual ~file_audio_stream_base() { return; } diff --git a/openmpt123/openmpt123_allegro42.hpp b/openmpt123/openmpt123_allegro42.hpp new file mode 100644 index 0000000..87cf1bf --- /dev/null +++ b/openmpt123/openmpt123_allegro42.hpp @@ -0,0 +1,176 @@ +/* + * openmpt123_allegro42.hpp + * ------------------------ + * Purpose: libopenmpt command line player + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef OPENMPT123_ALLEGRO42_HPP +#define OPENMPT123_ALLEGRO42_HPP + +#include "openmpt123_config.hpp" +#include "openmpt123.hpp" + +#if defined(MPT_WITH_ALLEGRO42) + +#include <allegro.h> + +namespace openmpt123 { + +struct allegro42_exception : public exception { + static std::string error_to_string() { + try { + return allegro_error ? std::string( allegro_error ) : std::string(); + } catch ( const std::bad_alloc & ) { + return std::string(); + } + } + allegro42_exception() + : exception( error_to_string() ) + { + } +}; + +class allegro42_raii { +public: + allegro42_raii() { + if ( allegro_init() != 0 ) { + throw allegro42_exception(); + } + } + ~allegro42_raii() { + allegro_exit(); + } +}; + +class allegro42_sound_raii { +public: + allegro42_sound_raii() { + if ( install_sound( DIGI_AUTODETECT, MIDI_NONE, NULL ) != 0 ) { + throw allegro42_exception(); + } + if ( digi_card == DIGI_NONE ) { + remove_sound(); + throw exception( "no audio device found" ); + } + } + ~allegro42_sound_raii() { + remove_sound(); + } +}; + +class allegro42_stream_raii : public write_buffers_polling_wrapper_int { +private: + allegro42_raii allegro; + allegro42_sound_raii allegro_sound; + AUDIOSTREAM * stream; + std::size_t bits; + std::size_t channels; + std::uint32_t period_frames; +private: + std::uint32_t round_up_power2(std::uint32_t x) + { + std::uint32_t result = 1; + while ( result < x ) { + result *= 2; + } + return result; + } +public: + allegro42_stream_raii( commandlineflags & flags, std::ostream & log ) + : write_buffers_polling_wrapper_int(flags) + , stream(NULL) + , bits(16) + , channels(flags.channels) + , period_frames(1024) + { + if ( flags.use_float ) { + throw exception( "floating point is unsupported" ); + } + if ( ( flags.channels != 1 ) && ( flags.channels != 2 ) ) { + throw exception( "only mono or stereo supported" ); + } + if ( flags.buffer == default_high ) { + flags.buffer = 1024 * 2 * 1000 / flags.samplerate; + } else if ( flags.buffer == default_low ) { + flags.buffer = 512 * 2 * 1000 / flags.samplerate; + } + if ( flags.period == default_high ) { + flags.period = 1024 / 2 * 1000 / flags.samplerate; + } else if ( flags.period == default_low ) { + flags.period = 512 / 2 * 1000 / flags.samplerate; + } + flags.apply_default_buffer_sizes(); + period_frames = round_up_power2( ( flags.buffer * flags.samplerate ) / ( 1000 * 2 ) ); + set_queue_size_frames( period_frames ); + if ( flags.verbose ) { + log << "Allegro-4.2:" << std::endl; + log << " latency: " << flags.buffer << std::endl; + log << " period: " << flags.period << std::endl; + log << " frames per buffer: " << period_frames << std::endl; + log << " ui redraw: " << flags.ui_redraw_interval << std::endl; + } + stream = play_audio_stream( period_frames, 16, ( flags.channels > 1 ) ? TRUE : FALSE, flags.samplerate, 255, 128 ); + if ( !stream ) { + bits = 8; + stream = play_audio_stream( period_frames, 8, ( flags.channels > 1 ) ? TRUE : FALSE, flags.samplerate, 255, 128 ); + if ( !stream ) { + throw allegro42_exception(); + } + } + } + ~allegro42_stream_raii() { + if ( stream ) { + stop_audio_stream( stream ); + stream = NULL; + } + } +public: + bool forward_queue() override { + void * p = get_audio_stream_buffer( stream ); + if ( !p ) { + return false; + } + for ( std::size_t frame = 0; frame < period_frames; ++frame ) { + for ( std::size_t channel = 0; channel < channels; ++channel ) { + std::int16_t sample = pop_queue(); + if ( bits == 8 ) { + std::uint8_t u8sample = ( static_cast<std::uint16_t>( sample ) + 0x8000u ) >> 8; + std::memcpy( reinterpret_cast<unsigned char *>( p ) + ( ( ( frame * channels ) + channel ) * sizeof( std::uint8_t ) ), &u8sample, sizeof( std::uint8_t ) ); + } else { + std::uint16_t u16sample = static_cast<std::uint16_t>( sample ) + 0x8000u; + std::memcpy( reinterpret_cast<unsigned char *>( p ) + ( ( ( frame * channels ) + channel ) * sizeof( std::uint16_t ) ), &u16sample, sizeof( std::uint16_t ) ); + } + } + } + free_audio_stream_buffer( stream ); + return true; + } + bool unpause() override { + voice_start( stream->voice ); + return true; + } + bool pause() override { + voice_stop( stream->voice ); + return true; + } + bool sleep( int ms ) override { + rest( ms ); + return true; + } +}; + +static std::string show_allegro42_devices( std::ostream & /* log */ ) { + std::ostringstream devices; + devices << " allegro42:" << std::endl; + devices << " " << "0" << ": Default Device" << std::endl; + return devices.str(); +} + +} // namespace openmpt123 + +#endif // MPT_WITH_ALLEGRO42 + +#endif // OPENMPT123_ALLEGRO42_HPP diff --git a/openmpt123/openmpt123_flac.hpp b/openmpt123/openmpt123_flac.hpp index 037931c..bc5b756 100644 --- a/openmpt123/openmpt123_flac.hpp +++ b/openmpt123/openmpt123_flac.hpp @@ -66,7 +66,7 @@ public: flac_metadata[0] = 0; } } - void write_metadata( std::map<std::string,std::string> metadata ) { + void write_metadata( std::map<std::string,std::string> metadata ) override { if ( called_init ) { return; } @@ -91,7 +91,7 @@ public: } FLAC__stream_encoder_set_metadata( encoder, flac_metadata, 1 ); } - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { if ( !called_init ) { FLAC__stream_encoder_init_file( encoder, filename.c_str(), NULL, 0 ); called_init = true; @@ -113,7 +113,7 @@ public: } FLAC__stream_encoder_process_interleaved( encoder, interleaved_buffer.data(), static_cast<unsigned int>( frames ) ); } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { if ( !called_init ) { FLAC__stream_encoder_init_file( encoder, filename.c_str(), NULL, 0 ); called_init = true; diff --git a/openmpt123/openmpt123_mmio.hpp b/openmpt123/openmpt123_mmio.hpp index 097d35c..cb44587 100644 --- a/openmpt123/openmpt123_mmio.hpp +++ b/openmpt123/openmpt123_mmio.hpp @@ -88,7 +88,7 @@ public: } - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { if ( data_info.pchEndWrite - data_info.pchNext < static_cast<long>( sizeof( float ) ) ) { @@ -101,7 +101,7 @@ public: } } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { if ( data_info.pchEndWrite - data_info.pchNext < static_cast<long>( sizeof( std::int16_t ) ) ) { diff --git a/openmpt123/openmpt123_portaudio.hpp b/openmpt123/openmpt123_portaudio.hpp index e598b86..7506514 100644 --- a/openmpt123/openmpt123_portaudio.hpp +++ b/openmpt123/openmpt123_portaudio.hpp @@ -205,7 +205,7 @@ private: } } public: - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { if ( interleaved ) { sampleBufFloat.clear(); for ( std::size_t frame = 0; frame < frames; ++frame ) { @@ -218,7 +218,7 @@ public: write_frames( buffers, frames ); } } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { if ( interleaved ) { sampleBufInt.clear(); for ( std::size_t frame = 0; frame < frames; ++frame ) { @@ -231,15 +231,15 @@ public: write_frames( buffers, frames ); } } - bool unpause() { + bool unpause() override { check_portaudio_error( Pa_StartStream( stream ) ); return true; } - bool pause() { + bool pause() override { check_portaudio_error( Pa_StopStream( stream ) ); return true; } - bool sleep( int ms ) { + bool sleep( int ms ) override { Pa_Sleep( ms ); return true; } diff --git a/openmpt123/openmpt123_pulseaudio.hpp b/openmpt123/openmpt123_pulseaudio.hpp index 389a60a..9650005 100644 --- a/openmpt123/openmpt123_pulseaudio.hpp +++ b/openmpt123/openmpt123_pulseaudio.hpp @@ -117,7 +117,7 @@ private: } } public: - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { sampleBufFloat.clear(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { @@ -126,7 +126,7 @@ public: } write_frames( sampleBufFloat.data(), frames ); } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { sampleBufInt.clear(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { @@ -135,10 +135,10 @@ public: } write_frames( sampleBufInt.data(), frames ); } - bool unpause() { + bool unpause() override { return true; } - bool pause() { + bool pause() override { int error = 0; error = 0; if ( pa_simple_drain( stream, &error ) < 0 ) { @@ -146,7 +146,7 @@ public: } return true; } - bool sleep( int ms ) { + bool sleep( int ms ) override { pa_msleep( ms ); return true; } diff --git a/openmpt123/openmpt123_raw.hpp b/openmpt123/openmpt123_raw.hpp index 25b2e25..cb7d8d5 100644 --- a/openmpt123/openmpt123_raw.hpp +++ b/openmpt123/openmpt123_raw.hpp @@ -30,10 +30,10 @@ public: ~raw_stream_raii() { return; } - void write_metadata( std::map<std::string,std::string> /* metadata */ ) { + void write_metadata( std::map<std::string,std::string> /* metadata */ ) override { return; } - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { interleaved_float_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { @@ -42,7 +42,7 @@ public: } file.write( reinterpret_cast<const char *>( interleaved_float_buffer.data() ), frames * buffers.size() * sizeof( float ) ); } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { interleaved_int_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { diff --git a/openmpt123/openmpt123_sdl.hpp b/openmpt123/openmpt123_sdl.hpp index da444f3..55d64e0 100644 --- a/openmpt123/openmpt123_sdl.hpp +++ b/openmpt123/openmpt123_sdl.hpp @@ -105,21 +105,21 @@ private: } } public: - bool pause() { + bool pause() override { SDL_PauseAudio( 1 ); return true; } - bool unpause() { + bool unpause() override { SDL_PauseAudio( 0 ); return true; } - void lock() { + void lock() override { SDL_LockAudio(); } - void unlock() { + void unlock() override { SDL_UnlockAudio(); } - bool sleep( int ms ) { + bool sleep( int ms ) override { SDL_Delay( ms ); return true; } diff --git a/openmpt123/openmpt123_sdl2.hpp b/openmpt123/openmpt123_sdl2.hpp index eec2737..307d67f 100644 --- a/openmpt123/openmpt123_sdl2.hpp +++ b/openmpt123/openmpt123_sdl2.hpp @@ -132,21 +132,21 @@ private: } } public: - bool pause() { + bool pause() override { SDL_PauseAudioDevice( dev, 1 ); return true; } - bool unpause() { + bool unpause() override { SDL_PauseAudioDevice( dev, 0 ); return true; } - void lock() { + void lock() override { SDL_LockAudioDevice( dev ); } - void unlock() { + void unlock() override { SDL_UnlockAudioDevice( dev ); } - bool sleep( int ms ) { + bool sleep( int ms ) override { SDL_Delay( ms ); return true; } diff --git a/openmpt123/openmpt123_sndfile.hpp b/openmpt123/openmpt123_sndfile.hpp index 533d2c2..8fc3156 100644 --- a/openmpt123/openmpt123_sndfile.hpp +++ b/openmpt123/openmpt123_sndfile.hpp @@ -174,14 +174,14 @@ public: sf_close( sndfile ); sndfile = 0; } - void write_metadata( std::map<std::string,std::string> metadata ) { + void write_metadata( std::map<std::string,std::string> metadata ) override { write_metadata_field( SF_STR_TITLE, metadata[ "title" ] ); write_metadata_field( SF_STR_ARTIST, metadata[ "artist" ] ); write_metadata_field( SF_STR_DATE, metadata[ "date" ] ); write_metadata_field( SF_STR_COMMENT, metadata[ "message" ] ); write_metadata_field( SF_STR_SOFTWARE, append_software_tag( metadata[ "tracker" ] ) ); } - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { interleaved_float_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { @@ -190,7 +190,7 @@ public: } sf_writef_float( sndfile, interleaved_float_buffer.data(), frames ); } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { interleaved_int_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { diff --git a/openmpt123/openmpt123_stdout.hpp b/openmpt123/openmpt123_stdout.hpp index 6b18198..585ce91 100644 --- a/openmpt123/openmpt123_stdout.hpp +++ b/openmpt123/openmpt123_stdout.hpp @@ -24,7 +24,7 @@ public: return; } public: - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { interleaved_float_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { @@ -33,7 +33,7 @@ public: } std::cout.write( reinterpret_cast<const char *>( interleaved_float_buffer.data() ), interleaved_float_buffer.size() * sizeof( float ) ); } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { interleaved_int_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { diff --git a/openmpt123/openmpt123_waveout.hpp b/openmpt123/openmpt123_waveout.hpp index baf7b99..e19a064 100644 --- a/openmpt123/openmpt123_waveout.hpp +++ b/openmpt123/openmpt123_waveout.hpp @@ -157,21 +157,21 @@ private: write_or_wait(); } public: - void write( const std::vector<float*> buffers, std::size_t frames ) { + void write( const std::vector<float*> buffers, std::size_t frames ) override { write_buffers( buffers, frames ); } - void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { + void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) override { write_buffers( buffers, frames ); } - bool pause() { + bool pause() override { waveOutPause( waveout ); return true; } - bool unpause() { + bool unpause() override { waveOutRestart( waveout ); return true; } - bool sleep( int ms ) { + bool sleep( int ms ) override { Sleep( ms ); return true; } |