annotate foosdk/sdk/foobar2000/SDK/play_callback.h @ 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "callback_merit.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 // IMPLEMENTATION NOTE: all callback methods declared here could not be declared noexcept for historical reasons, but it's strongly recommended that your overrides of these methods are noexcept.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 /*!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 Class receiving notifications about playback events. Note that all methods are called only from app's main thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 Use play_callback_manager to register your dynamically created instances. Statically registered version is available too - see play_callback_static.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 class NOVTABLE play_callback {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 //! Playback process is being initialized. on_playback_new_track() should be called soon after this when first file is successfully opened for decoding.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 virtual void on_playback_starting(play_control::t_track_command p_command,bool p_paused) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 //! Playback advanced to new track.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 virtual void on_playback_new_track(metadb_handle_ptr p_track) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 //! Playback stopped.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 virtual void on_playback_stop(play_control::t_stop_reason p_reason) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 //! User has seeked to specific time.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 virtual void on_playback_seek(double p_time) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 //! Called on pause/unpause.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 virtual void on_playback_pause(bool p_state) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 //! Called when currently played file gets edited.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 virtual void on_playback_edited(metadb_handle_ptr p_track) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 //! Dynamic info (VBR bitrate etc) change.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 virtual void on_playback_dynamic_info(const file_info & p_info) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 //! Per-track dynamic info (stream track titles etc) change. Happens less often than on_playback_dynamic_info().
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 virtual void on_playback_dynamic_info_track(const file_info & p_info) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 //! Called every second, for time display
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 virtual void on_playback_time(double p_time) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 //! User changed volume settings. Possibly called when not playing.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 //! @param p_new_val new volume level in dB; 0 for full volume.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 virtual void on_volume_change(float p_new_val) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 enum {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 flag_on_playback_starting = 1 << 0,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 flag_on_playback_new_track = 1 << 1,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 flag_on_playback_stop = 1 << 2,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 flag_on_playback_seek = 1 << 3,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 flag_on_playback_pause = 1 << 4,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 flag_on_playback_edited = 1 << 5,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 flag_on_playback_dynamic_info = 1 << 6,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 flag_on_playback_dynamic_info_track = 1 << 7,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 flag_on_playback_time = 1 << 8,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 flag_on_volume_change = 1 << 9,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 flag_on_playback_all = flag_on_playback_starting | flag_on_playback_new_track |
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 flag_on_playback_stop | flag_on_playback_seek |
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 flag_on_playback_pause | flag_on_playback_edited |
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 flag_on_playback_dynamic_info | flag_on_playback_dynamic_info_track | flag_on_playback_time,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 protected:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 play_callback() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 ~play_callback() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 //! Standard API (always present); manages registrations of dynamic play_callbacks. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 //! Usage: use play_callback_manager::get() to obtain on instance. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 //! Do not reimplement.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 class NOVTABLE play_callback_manager : public service_base {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 FB2K_MAKE_SERVICE_COREAPI(play_callback_manager);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 //! Registers a play_callback object.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 //! @param p_callback Interface to register.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 //! @param p_flags Indicates which notifications are requested.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 //! @param p_forward_status_on_register Set to true to have the callback immediately receive current playback status as notifications if playback is active (eg. to receive info about playback process that started before our callback was registered).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 virtual void register_callback(play_callback * p_callback,unsigned p_flags,bool p_forward_status_on_register) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 //! Unregisters a play_callback object.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 //! @p_callback Previously registered interface to unregister.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 virtual void unregister_callback(play_callback * p_callback) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 //! \since 2.0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 class NOVTABLE play_callback_manager_v2 : public play_callback_manager {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 FB2K_MAKE_SERVICE_COREAPI_EXTENSION(play_callback_manager_v2, play_callback_manager);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 virtual void set_callback_merit(play_callback*, fb2k::callback_merit_t) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 //! Implementation helper.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 class play_callback_impl_base : public play_callback {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 play_callback_impl_base(unsigned p_flags = 0xFFFFFFFF) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 if (p_flags != 0) play_callback_manager::get()->register_callback(this,p_flags,false);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 ~play_callback_impl_base() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 play_callback_manager::get()->unregister_callback(this);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 void play_callback_reregister(unsigned flags, bool refresh = false) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 auto api = play_callback_manager::get();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 api->unregister_callback(this);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 if (flags != 0) api->register_callback(this,flags,refresh);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 void on_playback_starting(play_control::t_track_command p_command, bool p_paused) override { (void)p_command; (void)p_paused; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 void on_playback_new_track(metadb_handle_ptr p_track) override { (void)p_track; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 void on_playback_stop(play_control::t_stop_reason p_reason) override { (void)p_reason; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 void on_playback_seek(double p_time) override { (void)p_time; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 void on_playback_pause(bool p_state) override { (void)p_state; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 void on_playback_edited(metadb_handle_ptr p_track) override { (void)p_track; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 void on_playback_dynamic_info(const file_info& p_info) override { (void)p_info; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 void on_playback_dynamic_info_track(const file_info& p_info) override { (void)p_info; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 void on_playback_time(double p_time) override { (void)p_time; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 void on_volume_change(float p_new_val) override { (void)p_new_val; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 PFC_CLASS_NOT_COPYABLE_EX(play_callback_impl_base)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 //! Static (autoregistered) version of play_callback. Use play_callback_static_factory_t to register.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 class play_callback_static : public service_base, public play_callback {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(play_callback_static);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 //! Controls which methods your callback wants called; returned value should not change in run time, you should expect it to be queried only once (on startup). See play_callback::flag_* constants.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 virtual unsigned get_flags() = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 class play_callback_static_factory_t : public service_factory_single_t<T> {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 //! Gets notified about tracks being played. Notification occurs when at least 60s of the track has been played, or the track has reached its end after at least 1/3 of it has been played through.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 //! Use playback_statistics_collector_factory_t to register.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 class NOVTABLE playback_statistics_collector : public service_base {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playback_statistics_collector);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 virtual void on_item_played(metadb_handle_ptr p_item) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 class playback_statistics_collector_factory_t : public service_factory_single_t<T> {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 //! Helper providing a simplified interface for receiving playback events, in case your code does not care about the kind of playback event that has occurred; useful typically for GUI/rendering code that just refreshes some control whenever a playback state change occurs.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 class playback_event_notify : private play_callback_impl_base {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 playback_event_notify(playback_control::t_display_level level = playback_control::display_level_all) : play_callback_impl_base(GrabCBFlags(level)) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 static t_uint32 GrabCBFlags(playback_control::t_display_level level) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 t_uint32 flags = flag_on_playback_starting | flag_on_playback_new_track | flag_on_playback_stop | flag_on_playback_pause | flag_on_playback_edited | flag_on_volume_change;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 if (level >= playback_control::display_level_titles) flags |= flag_on_playback_dynamic_info_track;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 if (level >= playback_control::display_level_all) flags |= flag_on_playback_seek | flag_on_playback_dynamic_info | flag_on_playback_time;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 return flags;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 protected:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 virtual void on_playback_event() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 void on_playback_starting(play_control::t_track_command,bool) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 void on_playback_new_track(metadb_handle_ptr) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 void on_playback_stop(play_control::t_stop_reason) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 void on_playback_seek(double) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 void on_playback_pause(bool) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 void on_playback_edited(metadb_handle_ptr) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 void on_playback_dynamic_info(const file_info &) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 void on_playback_dynamic_info_track(const file_info &) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 void on_playback_time(double) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 void on_volume_change(float) override {on_playback_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 class playback_volume_notify : private play_callback_impl_base {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 playback_volume_notify() : play_callback_impl_base(flag_on_volume_change) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 // override me
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 void on_volume_change(float p_new_val) override { (void)p_new_val; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 };