libopenmpt  0.2.6401
cross-platform C++ and C library to decode tracked music files
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
C++ API

Error Handling

libopenmpt C++ uses C++ exception handling for errror reporting.

Unless otherwise noted, any libopenmpt function may throw exceptions and all exceptions thrown by libopenmpt itself are derived from openmpt::exception. In addition, any libopenmpt function may also throw any exception specified by the C++ language and C++ standard library. These are all derived from std::exception.

Strings

  • All strings returned from libopenmpt are encoded in UTF-8.
  • All strings passed to libopenmpt should also be encoded in UTF-8. Behaviour in case of invalid UTF-8 is unspecified.
  • libopenmpt does not enforce or expect any particular unicode normalization form.

File I/O

libopenmpt can use 3 different strategies for file I/O.

  • openmpt::module::module() with any kind of memory buffer as parameter will load the module from the provided memory buffer, which will require loading all data upfront by the library caller.
  • openmpt::module::module() with a seekable std::istream as parameter will load the module via the stream interface. libopenmpt will not implement an additional buffering layer in this case whih means the callbacks are assumed to be performant even with small i/o sizes.
  • openmpt::module::module() with an unseekable std::istream as parameter will load the module via the stream interface. libopempt will make an internal copy as it goes along, and sometimes have to pre-cache the whole file in case it needs to know the complete file size. This strategy is intended to be used if the file is located on a high latency network.
constructor speed memory consumption
memory buffer

fast

medium

seekable stream

slow

low

unseekable stream

medium

high

In all cases, the data or stream passed to the constructor is no longer needed after the openmpt::module has been constructed and can be destroyed by the caller.

Detailed documentation

libopenmpt C++

Example

/*
* libopenmpt_example_cxx.cpp
* --------------------------
* Purpose: libopenmpt C++ API example
* Notes : PortAudio C++ is used for sound output.
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
/*
* Usage: libopenmpt_example_cxx SOMEMODULE
*/
#include <exception>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <vector>
#include <portaudiocpp/PortAudioCpp.hxx>
#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
#if defined( __GNUC__ )
// mingw-w64 g++ does only default to special C linkage for "main", but not for "wmain" (see <https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/>).
extern "C" int wmain( int argc, wchar_t * argv[] ) {
#else
int wmain( int argc, wchar_t * argv[] ) {
#endif
#else
int main( int argc, char * argv[] ) {
#endif
try {
if ( argc != 2 ) {
throw std::runtime_error( "Usage: libopenmpt_example_cxx SOMEMODULE" );
}
const std::size_t buffersize = 480;
const std::int32_t samplerate = 48000;
std::vector<float> left( buffersize );
std::vector<float> right( buffersize );
const float * const buffers[2] = { left.data(), right.data() };
std::ifstream file( argv[1], std::ios::binary );
openmpt::module mod( file );
portaudio::AutoSystem portaudio_initializer;
portaudio::System & portaudio = portaudio::System::instance();
portaudio::DirectionSpecificStreamParameters outputstream_parameters( portaudio.defaultOutputDevice(), 2, portaudio::FLOAT32, false, portaudio.defaultOutputDevice().defaultHighOutputLatency(), 0 );
portaudio::StreamParameters stream_parameters( portaudio::DirectionSpecificStreamParameters::null(), outputstream_parameters, samplerate, paFramesPerBufferUnspecified, paNoFlag );
portaudio::BlockingStream stream( stream_parameters );
stream.start();
while ( true ) {
std::size_t count = mod.read( samplerate, buffersize, left.data(), right.data() );
if ( count == 0 ) {
break;
}
try {
stream.write( buffers, static_cast<unsigned long>( count ) );
} catch ( const portaudio::PaException & pa_exception ) {
if ( pa_exception.paError() != paOutputUnderflowed ) {
throw;
}
}
}
stream.stop();
} catch ( const std::exception & e ) {
std::cerr << "Error: " << std::string( e.what() ? e.what() : "unknown error" ) << std::endl;
return 1;
}
return 0;
}