#include "../include/PlaybackEngine.h" #include "../include/miniaudio.h" #include #include using PE = PlaybackEngine; PE::PlaybackEngine () { configureDecoder(); configureDevice(); } PE::~PlaybackEngine () { ma_device_uninit ( &device_ ); ma_decoder_uninit ( &state.decoder ); } void PE::data_callback ( ma_device *pDevice, void *pOutput, const void *, ma_uint32 frameCount ) { std::unique_ptr state = std::unique_ptr ( static_cast ( pDevice->pUserData ) ); ma_uint64 framesRead = 0; ma_result result = ma_decoder_read_pcm_frames ( &state->decoder, pOutput, frameCount, &framesRead ); if ( result != MA_SUCCESS || framesRead < frameCount ) { state->finished.store ( true ); } }; void PE::configureDevice () { ma_device_config deviceConfig = ma_device_config_init ( ma_device_type_playback ); deviceConfig.playback.format = state.decoder.outputFormat; deviceConfig.playback.channels = state.decoder.outputChannels; deviceConfig.sampleRate = state.decoder.outputSampleRate; deviceConfig.dataCallback = PE::data_callback; deviceConfig.pUserData = &state; } void PE::configureDecoder () { ma_decoder_config decoderConfig = ma_decoder_config_init ( format_, 0, sampleRate_ ); } void PE::initDevice () { if ( ma_device_init ( nullptr, &deviceConfig, &device_ ) != MA_SUCCESS ) { throw std::runtime_error ( "failed to open file." ); } } void PE::initDecoder ( const char *filePath ) { if ( ma_decoder_init_file ( filePath, &decoderConfig, &state.decoder ) != MA_SUCCESS ) { throw std::runtime_error ( "Failed to open {filePath}." ); } } void PE::uninitDecoder() { ma_decoder_uninit( &state.decoder ); } void PE::startPlayback () { // ma_decoder_init_file( filePath, &decoderConfig, &decoder ); if ( ma_device_start ( &device_ ) != MA_SUCCESS ) { throw std::runtime_error ( "Failed to start playback device.\n" ); ma_device_uninit ( &device_ ); ma_decoder_uninit ( &state.decoder ); } } void PE::stopPlayback () { ma_device_stop ( &device_ ); } void PE::seek ( ma_uint64 frame ) { auto decoder = state.decoder; ma_decoder_seek_to_pcm_frame ( &state.decoder, frame ); } uint64_t PE::getPosition () { ma_decoder_get_cursor_in_pcm_frames ( &state.decoder, &cursor_ ); return cursor_; }