libopenmpt_cxx.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /*
  2. * libopenmpt_cxx.cpp
  3. * ------------------
  4. * Purpose: libopenmpt C++ interface implementation
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "openmpt/all/BuildSettings.hpp"
  10. #include "libopenmpt_internal.h"
  11. #include "libopenmpt.hpp"
  12. #include "libopenmpt_ext.hpp"
  13. #include "libopenmpt_impl.hpp"
  14. #include "libopenmpt_ext_impl.hpp"
  15. #include <algorithm>
  16. #include <stdexcept>
  17. #include <cstdlib>
  18. #include <cstring>
  19. namespace openmpt {
  20. exception::exception( const std::string & text_ ) noexcept
  21. : std::exception()
  22. , text(0)
  23. {
  24. text = static_cast<char*>( std::malloc( text_.length() + 1 ) );
  25. if ( text ) {
  26. std::memcpy( text, text_.c_str(), text_.length() + 1 );
  27. }
  28. }
  29. exception::exception( const exception & other ) noexcept
  30. : std::exception()
  31. , text(0)
  32. {
  33. const char * const text_ = ( other.what() ? other.what() : "" );
  34. text = static_cast<char*>( std::malloc( std::strlen( text_ ) + 1 ) );
  35. if ( text ) {
  36. std::memcpy( text, text_, std::strlen( text_ ) + 1 );
  37. }
  38. }
  39. exception::exception( exception && other ) noexcept
  40. : std::exception()
  41. , text(0)
  42. {
  43. text = std::move( other.text );
  44. other.text = 0;
  45. }
  46. exception & exception::operator = ( const exception & other ) noexcept {
  47. if ( this == &other ) {
  48. return *this;
  49. }
  50. if ( text ) {
  51. std::free( text );
  52. text = 0;
  53. }
  54. const char * const text_ = ( other.what() ? other.what() : "" );
  55. text = static_cast<char*>( std::malloc( std::strlen( text_ ) + 1 ) );
  56. if ( text ) {
  57. std::memcpy( text, text_, std::strlen( text_ ) + 1 );
  58. }
  59. return *this;
  60. }
  61. exception & exception::operator = ( exception && other ) noexcept {
  62. if ( this == &other ) {
  63. return *this;
  64. }
  65. if ( text ) {
  66. std::free( text );
  67. text = 0;
  68. }
  69. text = std::move( other.text );
  70. other.text = 0;
  71. return *this;
  72. }
  73. exception::~exception() noexcept {
  74. if ( text ) {
  75. std::free( text );
  76. text = 0;
  77. }
  78. }
  79. const char * exception::what() const noexcept {
  80. if ( text ) {
  81. return text;
  82. } else {
  83. return "out of memory";
  84. }
  85. }
  86. std::uint32_t get_library_version() {
  87. return openmpt::version::get_library_version();
  88. }
  89. std::uint32_t get_core_version() {
  90. return openmpt::version::get_core_version();
  91. }
  92. namespace string {
  93. std::string get( const std::string & key ) {
  94. return openmpt::version::get_string( key );
  95. }
  96. } // namespace string
  97. } // namespace openmpt
  98. namespace openmpt {
  99. std::vector<std::string> get_supported_extensions() {
  100. return openmpt::module_impl::get_supported_extensions();
  101. }
  102. bool is_extension_supported( const std::string & extension ) {
  103. return openmpt::module_impl::is_extension_supported( extension );
  104. }
  105. bool is_extension_supported2( std::string_view extension ) {
  106. return openmpt::module_impl::is_extension_supported( extension );
  107. }
  108. double could_open_probability( std::istream & stream, double effort, std::ostream & log ) {
  109. return openmpt::module_impl::could_open_probability( stream, effort, openmpt::helper::make_unique<std_ostream_log>( log ) );
  110. }
  111. double could_open_propability( std::istream & stream, double effort, std::ostream & log ) {
  112. return openmpt::module_impl::could_open_probability( stream, effort, openmpt::helper::make_unique<std_ostream_log>( log ) );
  113. }
  114. std::size_t probe_file_header_get_recommended_size() {
  115. return openmpt::module_impl::probe_file_header_get_recommended_size();
  116. }
  117. int probe_file_header( std::uint64_t flags, const std::byte * data, std::size_t size, std::uint64_t filesize ) {
  118. return openmpt::module_impl::probe_file_header( flags, data, size, filesize );
  119. }
  120. int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size, std::uint64_t filesize ) {
  121. return openmpt::module_impl::probe_file_header( flags, data, size, filesize );
  122. }
  123. int probe_file_header( std::uint64_t flags, const std::byte * data, std::size_t size ) {
  124. return openmpt::module_impl::probe_file_header( flags, data, size );
  125. }
  126. int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size ) {
  127. return openmpt::module_impl::probe_file_header( flags, data, size );
  128. }
  129. int probe_file_header( std::uint64_t flags, std::istream & stream ) {
  130. return openmpt::module_impl::probe_file_header( flags, stream );
  131. }
  132. #if defined(_MSC_VER)
  133. #pragma warning(push)
  134. #pragma warning(disable:4702) // unreachable code
  135. #endif // _MSC_VER
  136. module::module( const module & ) : impl(nullptr) {
  137. throw exception("openmpt::module is non-copyable");
  138. }
  139. // cppcheck-suppress operatorEqVarError
  140. void module::operator = ( const module & ) {
  141. throw exception("openmpt::module is non-copyable");
  142. }
  143. #if defined(_MSC_VER)
  144. #pragma warning(pop)
  145. #endif // _MSC_VER
  146. module::module() : impl(0) {
  147. return;
  148. }
  149. void module::set_impl( module_impl * i ) {
  150. impl = i;
  151. }
  152. module::module( std::istream & stream, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  153. impl = new module_impl( stream, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  154. }
  155. module::module( const std::vector<std::byte> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  156. impl = new module_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  157. }
  158. module::module( const std::byte * beg, const std::byte * end, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  159. impl = new module_impl( beg, end - beg, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  160. }
  161. module::module( const std::byte * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  162. impl = new module_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  163. }
  164. module::module( const std::vector<std::uint8_t> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  165. impl = new module_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  166. }
  167. module::module( const std::uint8_t * beg, const std::uint8_t * end, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  168. impl = new module_impl( beg, end - beg, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  169. }
  170. module::module( const std::uint8_t * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  171. impl = new module_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  172. }
  173. module::module( const std::vector<char> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  174. impl = new module_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  175. }
  176. module::module( const char * beg, const char * end, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  177. impl = new module_impl( beg, end - beg, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  178. }
  179. module::module( const char * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  180. impl = new module_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  181. }
  182. module::module( const void * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
  183. impl = new module_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  184. }
  185. module::~module() {
  186. delete impl;
  187. impl = 0;
  188. }
  189. void module::select_subsong( std::int32_t subsong ) {
  190. impl->select_subsong( subsong );
  191. }
  192. std::int32_t module::get_selected_subsong() const {
  193. return impl->get_selected_subsong();
  194. }
  195. void module::set_repeat_count( std::int32_t repeat_count ) {
  196. impl->set_repeat_count( repeat_count );
  197. }
  198. std::int32_t module::get_repeat_count() const {
  199. return impl->get_repeat_count();
  200. }
  201. double module::get_duration_seconds() const {
  202. return impl->get_duration_seconds();
  203. }
  204. double module::set_position_seconds( double seconds ) {
  205. return impl->set_position_seconds( seconds );
  206. }
  207. double module::get_position_seconds() const {
  208. return impl->get_position_seconds();
  209. }
  210. double module::set_position_order_row( std::int32_t order, std::int32_t row ) {
  211. return impl->set_position_order_row( order, row );
  212. }
  213. std::int32_t module::get_render_param( int param ) const {
  214. return impl->get_render_param( param );
  215. }
  216. void module::set_render_param( int param, std::int32_t value ) {
  217. impl->set_render_param( param, value );
  218. }
  219. std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * mono ) {
  220. return impl->read( samplerate, count, mono );
  221. }
  222. std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right ) {
  223. return impl->read( samplerate, count, left, right );
  224. }
  225. std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ) {
  226. return impl->read( samplerate, count, left, right, rear_left, rear_right );
  227. }
  228. std::size_t module::read( std::int32_t samplerate, std::size_t count, float * mono ) {
  229. return impl->read( samplerate, count, mono );
  230. }
  231. std::size_t module::read( std::int32_t samplerate, std::size_t count, float * left, float * right ) {
  232. return impl->read( samplerate, count, left, right );
  233. }
  234. std::size_t module::read( std::int32_t samplerate, std::size_t count, float * left, float * right, float * rear_left, float * rear_right ) {
  235. return impl->read( samplerate, count, left, right, rear_left, rear_right );
  236. }
  237. std::size_t module::read_interleaved_stereo( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_stereo ) {
  238. return impl->read_interleaved_stereo( samplerate, count, interleaved_stereo );
  239. }
  240. std::size_t module::read_interleaved_quad( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_quad ) {
  241. return impl->read_interleaved_quad( samplerate, count, interleaved_quad );
  242. }
  243. std::size_t module::read_interleaved_stereo( std::int32_t samplerate, std::size_t count, float * interleaved_stereo ) {
  244. return impl->read_interleaved_stereo( samplerate, count, interleaved_stereo );
  245. }
  246. std::size_t module::read_interleaved_quad( std::int32_t samplerate, std::size_t count, float * interleaved_quad ) {
  247. return impl->read_interleaved_quad( samplerate, count, interleaved_quad );
  248. }
  249. std::vector<std::string> module::get_metadata_keys() const {
  250. return impl->get_metadata_keys();
  251. }
  252. std::string module::get_metadata( const std::string & key ) const {
  253. return impl->get_metadata( key );
  254. }
  255. double module::get_current_estimated_bpm() const {
  256. return impl->get_current_estimated_bpm();
  257. }
  258. std::int32_t module::get_current_speed() const {
  259. return impl->get_current_speed();
  260. }
  261. std::int32_t module::get_current_tempo() const {
  262. return impl->get_current_tempo();
  263. }
  264. std::int32_t module::get_current_order() const {
  265. return impl->get_current_order();
  266. }
  267. std::int32_t module::get_current_pattern() const {
  268. return impl->get_current_pattern();
  269. }
  270. std::int32_t module::get_current_row() const {
  271. return impl->get_current_row();
  272. }
  273. std::int32_t module::get_current_playing_channels() const {
  274. return impl->get_current_playing_channels();
  275. }
  276. float module::get_current_channel_vu_mono( std::int32_t channel ) const {
  277. return impl->get_current_channel_vu_mono( channel );
  278. }
  279. float module::get_current_channel_vu_left( std::int32_t channel ) const {
  280. return impl->get_current_channel_vu_left( channel );
  281. }
  282. float module::get_current_channel_vu_right( std::int32_t channel ) const {
  283. return impl->get_current_channel_vu_right( channel );
  284. }
  285. float module::get_current_channel_vu_rear_left( std::int32_t channel ) const {
  286. return impl->get_current_channel_vu_rear_left( channel );
  287. }
  288. float module::get_current_channel_vu_rear_right( std::int32_t channel ) const {
  289. return impl->get_current_channel_vu_rear_right( channel );
  290. }
  291. std::int32_t module::get_num_subsongs() const {
  292. return impl->get_num_subsongs();
  293. }
  294. std::int32_t module::get_num_channels() const {
  295. return impl->get_num_channels();
  296. }
  297. std::int32_t module::get_num_orders() const {
  298. return impl->get_num_orders();
  299. }
  300. std::int32_t module::get_num_patterns() const {
  301. return impl->get_num_patterns();
  302. }
  303. std::int32_t module::get_num_instruments() const {
  304. return impl->get_num_instruments();
  305. }
  306. std::int32_t module::get_num_samples() const {
  307. return impl->get_num_samples();
  308. }
  309. std::vector<std::string> module::get_subsong_names() const {
  310. return impl->get_subsong_names();
  311. }
  312. std::vector<std::string> module::get_channel_names() const {
  313. return impl->get_channel_names();
  314. }
  315. std::vector<std::string> module::get_order_names() const {
  316. return impl->get_order_names();
  317. }
  318. std::vector<std::string> module::get_pattern_names() const {
  319. return impl->get_pattern_names();
  320. }
  321. std::vector<std::string> module::get_instrument_names() const {
  322. return impl->get_instrument_names();
  323. }
  324. std::vector<std::string> module::get_sample_names() const {
  325. return impl->get_sample_names();
  326. }
  327. std::int32_t module::get_order_pattern( std::int32_t order ) const {
  328. return impl->get_order_pattern( order );
  329. }
  330. std::int32_t module::get_pattern_num_rows( std::int32_t pattern ) const {
  331. return impl->get_pattern_num_rows( pattern );
  332. }
  333. std::uint8_t module::get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
  334. return impl->get_pattern_row_channel_command( pattern, row, channel, command );
  335. }
  336. std::string module::format_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
  337. return impl->format_pattern_row_channel_command( pattern, row, channel, command );
  338. }
  339. std::string module::highlight_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
  340. return impl->highlight_pattern_row_channel_command( pattern, row, channel, command );
  341. }
  342. std::string module::format_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width, bool pad ) const {
  343. return impl->format_pattern_row_channel( pattern, row, channel, width, pad );
  344. }
  345. std::string module::highlight_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width, bool pad ) const {
  346. return impl->highlight_pattern_row_channel( pattern, row, channel, width, pad );
  347. }
  348. std::vector<std::string> module::get_ctls() const {
  349. return impl->get_ctls();
  350. }
  351. std::string module::ctl_get( const std::string & ctl ) const {
  352. return impl->ctl_get( ctl );
  353. }
  354. bool module::ctl_get_boolean( std::string_view ctl ) const {
  355. return impl->ctl_get_boolean( ctl );
  356. }
  357. std::int64_t module::ctl_get_integer( std::string_view ctl ) const {
  358. return impl->ctl_get_integer( ctl );
  359. }
  360. double module::ctl_get_floatingpoint( std::string_view ctl ) const {
  361. return impl->ctl_get_floatingpoint( ctl );
  362. }
  363. std::string module::ctl_get_text( std::string_view ctl ) const {
  364. return impl->ctl_get_text( ctl );
  365. }
  366. void module::ctl_set( const std::string & ctl, const std::string & value ) {
  367. impl->ctl_set( ctl, value );
  368. }
  369. void module::ctl_set_boolean( std::string_view ctl, bool value ) {
  370. impl->ctl_set_boolean( ctl, value );
  371. }
  372. void module::ctl_set_integer( std::string_view ctl, std::int64_t value ) {
  373. impl->ctl_set_integer( ctl, value );
  374. }
  375. void module::ctl_set_floatingpoint( std::string_view ctl, double value ) {
  376. impl->ctl_set_floatingpoint( ctl, value );
  377. }
  378. void module::ctl_set_text( std::string_view ctl, std::string_view value ) {
  379. impl->ctl_set_text( ctl, value );
  380. }
  381. module_ext::module_ext( std::istream & stream, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
  382. ext_impl = new module_ext_impl( stream, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  383. set_impl( ext_impl );
  384. }
  385. module_ext::module_ext( const std::vector<std::uint8_t> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
  386. ext_impl = new module_ext_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  387. set_impl( ext_impl );
  388. }
  389. module_ext::module_ext( const std::vector<char> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
  390. ext_impl = new module_ext_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  391. set_impl( ext_impl );
  392. }
  393. module_ext::module_ext( const std::vector<std::byte> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
  394. ext_impl = new module_ext_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  395. set_impl( ext_impl );
  396. }
  397. module_ext::module_ext( const std::uint8_t * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
  398. ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  399. set_impl( ext_impl );
  400. }
  401. module_ext::module_ext( const char * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
  402. ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  403. set_impl( ext_impl );
  404. }
  405. module_ext::module_ext( const std::byte * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
  406. ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  407. set_impl( ext_impl );
  408. }
  409. module_ext::module_ext( const void * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
  410. ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
  411. set_impl( ext_impl );
  412. }
  413. module_ext::~module_ext() {
  414. set_impl( 0 );
  415. delete ext_impl;
  416. ext_impl = 0;
  417. }
  418. #if defined(_MSC_VER)
  419. #pragma warning(push)
  420. #pragma warning(disable:4702) // unreachable code
  421. #endif // _MSC_VER
  422. module_ext::module_ext( const module_ext & other ) : module(other), ext_impl(nullptr) {
  423. throw std::runtime_error("openmpt::module_ext is non-copyable");
  424. }
  425. // cppcheck-suppress operatorEqVarError
  426. void module_ext::operator = ( const module_ext & ) {
  427. throw std::runtime_error("openmpt::module_ext is non-copyable");
  428. }
  429. #if defined(_MSC_VER)
  430. #pragma warning(pop)
  431. #endif // _MSC_VER
  432. void * module_ext::get_interface( const std::string & interface_id ) {
  433. return ext_impl->get_interface( interface_id );
  434. }
  435. } // namespace openmpt