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
#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__ )
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 );
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;
}