Mercurial > foo_out_sdl
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "stdafx.h" | |
| 2 #include <helpers/input_helpers.h> | |
| 3 | |
| 4 class calculate_peak_process : public threaded_process_callback { | |
| 5 public: | |
| 6 calculate_peak_process(metadb_handle_list_cref items) : m_items(items), m_peak() {} | |
| 7 void on_init(ctx_t p_wnd) override {} | |
| 8 void run(threaded_process_status & p_status,abort_callback & p_abort) override { | |
| 9 try { | |
| 10 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. | |
| 11 input_helper input; // this object manages lowlevel input_decoder calls for us. | |
| 12 for(t_size walk = 0; walk < m_items.get_size(); ++walk) { | |
| 13 p_abort.check(); // in case the input we're working with fails at doing this | |
| 14 p_status.set_progress(walk, m_items.get_size()); | |
| 15 p_status.set_progress_secondary(0); | |
| 16 p_status.set_item_path( m_items[walk]->get_path() ); | |
| 17 input.open(NULL, m_items[walk], decode_flags, p_abort); | |
| 18 | |
| 19 double length; | |
| 20 { // fetch the track length for proper dual progress display; | |
| 21 file_info_impl info; | |
| 22 // input.open should have preloaded relevant info, no need to query the input itself again. | |
| 23 // 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. | |
| 24 if (m_items[walk]->get_info_async(info)) length = info.get_length(); | |
| 25 else length = 0; | |
| 26 } | |
| 27 | |
| 28 audio_chunk_impl_temporary l_chunk; | |
| 29 double decoded = 0; | |
| 30 while(input.run(l_chunk, p_abort)) { // main decode loop | |
| 31 m_peak = l_chunk.get_peak(m_peak); | |
| 32 if (length > 0) { // don't bother for unknown length tracks | |
| 33 decoded += l_chunk.get_duration(); | |
| 34 if (decoded > length) decoded = length; | |
| 35 p_status.set_progress_secondary_float(decoded / length); | |
| 36 } | |
| 37 p_abort.check(); // in case the input we're working with fails at doing this | |
| 38 } | |
| 39 } | |
| 40 } catch(std::exception const & e) { | |
| 41 m_failMsg = e.what(); | |
| 42 } | |
| 43 } | |
| 44 void on_done(ctx_t p_wnd,bool p_was_aborted) override { | |
| 45 if (!p_was_aborted) { | |
| 46 if (!m_failMsg.is_empty()) { | |
| 47 popup_message::g_complain("Peak scan failure", m_failMsg); | |
| 48 } else { | |
| 49 pfc::string_formatter result; | |
| 50 result << "Value: " << m_peak << "\n\n"; | |
| 51 result << "Scanned items:\n"; | |
| 52 for(t_size walk = 0; walk < m_items.get_size(); ++walk) { | |
| 53 result << m_items[walk] << "\n"; | |
| 54 } | |
| 55 popup_message::g_show(result,"Peak scan result"); | |
| 56 } | |
| 57 } | |
| 58 } | |
| 59 private: | |
| 60 audio_sample m_peak; | |
| 61 pfc::string8 m_failMsg; | |
| 62 const metadb_handle_list m_items; | |
| 63 }; | |
| 64 | |
| 65 void RunCalculatePeak(metadb_handle_list_cref data) { | |
| 66 try { | |
| 67 if (data.get_count() == 0) throw pfc::exception_invalid_params(); | |
| 68 service_ptr_t<threaded_process_callback> cb = new service_impl_t<calculate_peak_process>(data); | |
| 69 static_api_ptr_t<threaded_process>()->run_modeless( | |
| 70 cb, | |
| 71 threaded_process::flag_show_progress_dual | threaded_process::flag_show_item | threaded_process::flag_show_abort, | |
| 72 core_api::get_main_window(), | |
| 73 "Sample component: peak scan"); | |
| 74 } catch(std::exception const & e) { | |
| 75 popup_message::g_complain("Could not start peak scan process", e); | |
| 76 } | |
| 77 } |
