Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/foo_sample/decode.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/foo_sample/decode.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,77 @@ +#include "stdafx.h" +#include <helpers/input_helpers.h> + +class calculate_peak_process : public threaded_process_callback { +public: + calculate_peak_process(metadb_handle_list_cref items) : m_items(items), m_peak() {} + void on_init(ctx_t p_wnd) override {} + void run(threaded_process_status & p_status,abort_callback & p_abort) override { + try { + const t_uint32 decode_flags = input_flag_no_seeking | input_flag_no_looping; // tell the decoders that we won't seek and that we don't want looping on formats that support looping. + input_helper input; // this object manages lowlevel input_decoder calls for us. + for(t_size walk = 0; walk < m_items.get_size(); ++walk) { + p_abort.check(); // in case the input we're working with fails at doing this + p_status.set_progress(walk, m_items.get_size()); + p_status.set_progress_secondary(0); + p_status.set_item_path( m_items[walk]->get_path() ); + input.open(NULL, m_items[walk], decode_flags, p_abort); + + double length; + { // fetch the track length for proper dual progress display; + file_info_impl info; + // input.open should have preloaded relevant info, no need to query the input itself again. + // Regular get_info() may not retrieve freshly loaded info yet at this point (it will start giving the new info when relevant info change callbacks are dispatched); we need to use get_info_async. + if (m_items[walk]->get_info_async(info)) length = info.get_length(); + else length = 0; + } + + audio_chunk_impl_temporary l_chunk; + double decoded = 0; + while(input.run(l_chunk, p_abort)) { // main decode loop + m_peak = l_chunk.get_peak(m_peak); + if (length > 0) { // don't bother for unknown length tracks + decoded += l_chunk.get_duration(); + if (decoded > length) decoded = length; + p_status.set_progress_secondary_float(decoded / length); + } + p_abort.check(); // in case the input we're working with fails at doing this + } + } + } catch(std::exception const & e) { + m_failMsg = e.what(); + } + } + void on_done(ctx_t p_wnd,bool p_was_aborted) override { + if (!p_was_aborted) { + if (!m_failMsg.is_empty()) { + popup_message::g_complain("Peak scan failure", m_failMsg); + } else { + pfc::string_formatter result; + result << "Value: " << m_peak << "\n\n"; + result << "Scanned items:\n"; + for(t_size walk = 0; walk < m_items.get_size(); ++walk) { + result << m_items[walk] << "\n"; + } + popup_message::g_show(result,"Peak scan result"); + } + } + } +private: + audio_sample m_peak; + pfc::string8 m_failMsg; + const metadb_handle_list m_items; +}; + +void RunCalculatePeak(metadb_handle_list_cref data) { + try { + if (data.get_count() == 0) throw pfc::exception_invalid_params(); + service_ptr_t<threaded_process_callback> cb = new service_impl_t<calculate_peak_process>(data); + static_api_ptr_t<threaded_process>()->run_modeless( + cb, + threaded_process::flag_show_progress_dual | threaded_process::flag_show_item | threaded_process::flag_show_abort, + core_api::get_main_window(), + "Sample component: peak scan"); + } catch(std::exception const & e) { + popup_message::g_complain("Could not start peak scan process", e); + } +}
