diff --git a/src/core/c_context.cpp b/src/core/c_context.cpp index 899e0da38..1affb3dc5 100644 --- a/src/core/c_context.cpp +++ b/src/core/c_context.cpp @@ -97,6 +97,42 @@ void mcsdk_context_message_queue::Run() { } } +/* + * mcsdk_svc_indexer_callback_proxy + */ + +struct mcsdk_svc_indexer_callback_proxy { + mcsdk_svc_indexer_context_internal* context; + + mcsdk_svc_indexer_callback_proxy(mcsdk_svc_indexer_context_internal* context) { + this->context = context; + } + + void on_started() { + for (auto cb : context->callbacks) { + if (cb->on_started) { + cb->on_started(mcsdk_svc_indexer { context }); + } + } + } + + void on_finished(int tracks_processed) { + for (auto cb : context->callbacks) { + if (cb->on_finished) { + cb->on_finished(mcsdk_svc_indexer { context }, tracks_processed); + } + } + } + + void on_progress(int tracks_processed) { + for (auto cb : context->callbacks) { + if (cb->on_progress) { + cb->on_progress(mcsdk_svc_indexer { context }, tracks_processed); + } + } + } +}; + /* * mcsdk_context_* */ @@ -111,24 +147,36 @@ mcsdk_export void mcsdk_context_init(mcsdk_context** context) { debug::Start(); environment_initialized = true; } + auto c = new mcsdk_context(); memset(c, 0, sizeof(mcsdk_context)); + auto internal = new mcsdk_context_internal(); + internal->library = LibraryFactory::Default(); internal->library->SetMessageQueue(internal->message_queue); internal->playback = new PlaybackService(internal->message_queue, internal->library); internal->metadata = new LocalMetadataProxy(internal->library); internal->preferences = Preferences::ForComponent(prefs::components::Settings); + c->internal.opaque = internal; c->metadata.opaque = internal->metadata; c->preferences.opaque = internal->preferences.get(); c->playback.opaque = internal->playback; + + auto indexer_internal = new mcsdk_svc_indexer_context_internal(); + indexer_internal->indexer = internal->library->Indexer(); + indexer_internal->callback_proxy = new mcsdk_svc_indexer_callback_proxy(indexer_internal); + c->indexer.opaque = indexer_internal; + if (!plugin_context) { mcsdk_set_plugin_context(c); } + internal->thread = std::thread([internal] { /* needs to be last */ internal->message_queue.Run(); }); + *context = c; } @@ -137,19 +185,31 @@ mcsdk_export void mcsdk_context_release(mcsdk_context** context) { auto c = *context; auto internal = static_cast(c->internal.opaque); + delete internal->playback; + internal->playback = nullptr; internal->library->Indexer()->Stop(); internal->library.reset(); internal->preferences.reset(); + delete internal->metadata; + internal->message_queue.Quit(); internal->thread.join(); + + auto indexer_internal = static_cast(c->indexer.opaque); + delete indexer_internal->callback_proxy; + delete indexer_internal; + delete internal; - delete c; + if (plugin_context == c) { mcsdk_set_plugin_context(nullptr); } + + delete c; + *context = 0; } diff --git a/src/core/c_context.h b/src/core/c_context.h index 278a94efd..061f0187a 100644 --- a/src/core/c_context.h +++ b/src/core/c_context.h @@ -37,8 +37,11 @@ #include #include #include +#include +#include #include +#include using namespace musik; using namespace musik::core; @@ -66,4 +69,21 @@ struct mcsdk_context_internal { LocalMetadataProxy* metadata; PlaybackService* playback; std::shared_ptr preferences; +}; + +struct mcsdk_svc_indexer_callback_proxy; + +struct mcsdk_svc_indexer_context_internal { + IIndexer* indexer; + mcsdk_svc_indexer_callback_proxy* callback_proxy; + std::set callbacks; +}; + +struct mcsdk_player_context_internal { + Player::EventListener* event_listener; + std::shared_ptr output; + std::mutex event_mutex; + std::condition_variable finished_condition; + Player* player; + bool player_finished; }; \ No newline at end of file diff --git a/src/core/c_interface_wrappers.cpp b/src/core/c_interface_wrappers.cpp index 80f160353..f4a018a7d 100644 --- a/src/core/c_interface_wrappers.cpp +++ b/src/core/c_interface_wrappers.cpp @@ -59,13 +59,12 @@ #include #include #include +#include #include #include #include #include -#include - using namespace musik; using namespace musik::core; using namespace musik::core::sdk; @@ -95,6 +94,8 @@ using namespace musik::core::audio; #define DEVICELIST(x) reinterpret_cast(x.opaque) #define OUTPUT(x) reinterpret_cast(x.opaque) #define AUDIOSTREAM(x) reinterpret_cast(x.opaque) +#define PLAYER(x) reinterpret_cast(x.opaque) +#define INDEXER(x) reinterpret_cast(x.opaque)->indexer #define RELEASE(x, type) if (mcsdk_handle_ok(x)) { type(x)->Release(); x.opaque = nullptr; } @@ -983,19 +984,10 @@ mcsdk_export void mcsdk_audio_stream_release(mcsdk_audio_stream as) { * Player */ -struct mcsdk_internal_player_context { - Player::EventListener* event_listener; - std::shared_ptr output; - std::mutex event_mutex; - std::condition_variable finished_condition; - Player* player; - bool player_finished; -}; - class mcsdk_audio_player_callback_proxy: public Player::EventListener { public: std::set callbacks; - mcsdk_internal_player_context* context; + mcsdk_player_context_internal* context; virtual void OnPlayerPrepared(Player *player) { std::unique_lock lock(this->context->event_mutex); for (auto c : callbacks) { @@ -1056,8 +1048,6 @@ class mcsdk_audio_player_callback_proxy: public Player::EventListener { } }; -#define PLAYER(x) reinterpret_cast(x.opaque) - mcsdk_export mcsdk_audio_player mcsdk_audio_player_create(const char* url, mcsdk_audio_output output, mcsdk_audio_player_callbacks* callbacks, mcsdk_audio_player_gain gain) { Player::Gain playerGain; playerGain.gain = gain.gain; @@ -1067,7 +1057,7 @@ mcsdk_export mcsdk_audio_player mcsdk_audio_player_create(const char* url, mcsdk auto callbackProxy = new mcsdk_audio_player_callback_proxy(); - mcsdk_internal_player_context* playerContext = new mcsdk_internal_player_context(); + mcsdk_player_context_internal* playerContext = new mcsdk_player_context_internal(); playerContext->event_listener = callbackProxy; playerContext->player_finished = false; @@ -1090,7 +1080,7 @@ mcsdk_export mcsdk_audio_player mcsdk_audio_player_create(const char* url, mcsdk } mcsdk_export int mcsdk_audio_player_get_url(mcsdk_audio_player ap, char* dst, int size) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { return (int) CopyString(context->player->GetUrl(), dst, size); @@ -1099,7 +1089,7 @@ mcsdk_export int mcsdk_audio_player_get_url(mcsdk_audio_player ap, char* dst, in } mcsdk_export void mcsdk_audio_player_detach(mcsdk_audio_player ap, mcsdk_audio_player_callbacks* callbacks) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { auto proxy = reinterpret_cast(context->event_listener); @@ -1111,7 +1101,7 @@ mcsdk_export void mcsdk_audio_player_detach(mcsdk_audio_player ap, mcsdk_audio_p } mcsdk_export void mcsdk_audio_player_attach(mcsdk_audio_player ap, mcsdk_audio_player_callbacks* callbacks) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { reinterpret_cast(context->event_listener)->callbacks.insert(callbacks); @@ -1119,7 +1109,7 @@ mcsdk_export void mcsdk_audio_player_attach(mcsdk_audio_player ap, mcsdk_audio_p } mcsdk_export void mcsdk_audio_player_play(mcsdk_audio_player ap) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { context->player->Play(); @@ -1127,7 +1117,7 @@ mcsdk_export void mcsdk_audio_player_play(mcsdk_audio_player ap) { } mcsdk_export double mcsdk_audio_player_get_position(mcsdk_audio_player ap) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { return context->player->GetPosition(); @@ -1136,7 +1126,7 @@ mcsdk_export double mcsdk_audio_player_get_position(mcsdk_audio_player ap) { } mcsdk_export void mcsdk_audio_player_set_position(mcsdk_audio_player ap, double seconds) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { context->player->SetPosition(seconds); @@ -1144,7 +1134,7 @@ mcsdk_export void mcsdk_audio_player_set_position(mcsdk_audio_player ap, double } mcsdk_export double mcsdk_audio_player_get_duration(mcsdk_audio_player ap) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { return context->player->GetDuration(); @@ -1153,7 +1143,7 @@ mcsdk_export double mcsdk_audio_player_get_duration(mcsdk_audio_player ap) { } mcsdk_export void mcsdk_audio_player_add_mix_point(mcsdk_audio_player ap, int id, double time) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { context->player->AddMixPoint(id, time); @@ -1161,7 +1151,7 @@ mcsdk_export void mcsdk_audio_player_add_mix_point(mcsdk_audio_player ap, int id } mcsdk_export bool mcsdk_audio_player_has_capability(mcsdk_audio_player ap, mcsdk_stream_capability capability) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); std::unique_lock lock(context->event_mutex); if (!context->player_finished) { return PLAYER(ap)->player->HasCapability((Capability) capability); @@ -1170,7 +1160,7 @@ mcsdk_export bool mcsdk_audio_player_has_capability(mcsdk_audio_player ap, mcsdk } mcsdk_export void mcsdk_audio_player_release(mcsdk_audio_player ap, mcsdk_audio_player_release_mode mode) { - mcsdk_internal_player_context* context = PLAYER(ap); + mcsdk_player_context_internal* context = PLAYER(ap); { std::unique_lock lock(context->event_mutex); @@ -1190,4 +1180,53 @@ mcsdk_export void mcsdk_audio_player_release(mcsdk_audio_player ap, mcsdk_audio_ mcsdk_export mcsdk_audio_player_gain mcsdk_audio_player_get_default_gain() { return mcsdk_audio_player_gain { 1.0, 1.0, 0.0, false }; +} +/* + * IIndexer + */ + +#define INDEXER_INTERNAL(x) reinterpret_cast(x.opaque) + +mcsdk_export void mcsdk_svc_indexer_add_path(mcsdk_svc_indexer in, const char* path) { + INDEXER(in)->AddPath(path); +} + +mcsdk_export void mcsdk_svc_indexer_remove_path(mcsdk_svc_indexer in, const char* path) { + INDEXER(in)->RemovePath(path); +} + +mcsdk_export int mcsdk_svc_indexer_get_paths_count(mcsdk_svc_indexer in) { + std::vector paths; + INDEXER(in)->GetPaths(paths); + return (int) paths.size(); +} + +mcsdk_export int mcsdk_svc_indexer_get_paths_at(mcsdk_svc_indexer in, int index, char* dst, int len) { + std::vector paths; + INDEXER(in)->GetPaths(paths); + return CopyString(paths[index], dst, (int) len); +} + +mcsdk_export void mcsdk_svc_indexer_schedule(mcsdk_svc_indexer in, mcsdk_svc_indexer_sync_type type) { + INDEXER(in)->Schedule((IIndexer::SyncType) type); +} + +mcsdk_export void mcsdk_svc_indexer_stop(mcsdk_svc_indexer in) { + INDEXER(in)->Stop(); +} + +mcsdk_export mcsdk_svc_indexer_state mcsdk_svc_indexer_get_state(mcsdk_svc_indexer in) { + return (mcsdk_svc_indexer_state) INDEXER(in)->GetState(); +} + +mcsdk_export void mcsdk_svc_indexer_add_callbacks(mcsdk_svc_indexer in, mcsdk_svc_indexer_callbacks* cb) { + INDEXER_INTERNAL(in)->callbacks.insert(cb); +} + +mcsdk_export void mcsdk_svc_indexer_remove_callbacks(mcsdk_svc_indexer in, mcsdk_svc_indexer_callbacks* cb) { + auto internal = INDEXER_INTERNAL(in); + auto it = internal->callbacks.find(cb); + if (it != internal->callbacks.end()) { + internal->callbacks.erase(it); + } } \ No newline at end of file diff --git a/src/core/library/IIndexer.h b/src/core/library/IIndexer.h index 4da3a770c..ee672ce8b 100755 --- a/src/core/library/IIndexer.h +++ b/src/core/library/IIndexer.h @@ -46,17 +46,17 @@ namespace musik { namespace core { sigslot::signal1 Progress; enum State { - StateIdle, - StateIndexing, - StateStopping, - StateStopped + StateIdle = 0, + StateIndexing = 1, + StateStopping = 2, + StateStopped = 3 }; enum class SyncType { - All, - Local, - Rebuild, - Sources + All = 0, + Local = 1, + Rebuild = 2, + Sources = 3 }; virtual ~IIndexer() { } diff --git a/src/core/musikcore_c.h b/src/core/musikcore_c.h index 6880f3715..a5a99f2d0 100644 --- a/src/core/musikcore_c.h +++ b/src/core/musikcore_c.h @@ -107,10 +107,24 @@ typedef enum mcsdk_stream_capability { mcsdk_stream_capability_prebuffer = 0x01 } mcsdk_stream_capability; -typedef enum mcsdk_indexer_scan_result { - mcsdk_indexer_scan_result_commit = 1, - mcsdk_indexer_scan_result_rollback = 2 -} mcsdk_indexer_scan_result; +typedef enum mcsdk_svc_indexer_scan_result { + mcsdk_svc_indexer_scan_result_commit = 1, + mcsdk_svc_indexer_scan_result_rollback = 2 +} mcsdk_svc_indexer_scan_result; + +typedef enum mcsdk_svc_indexer_state { + mcsdk_svc_indexer_state_idle = 0, + mcsdk_svc_indexer_state_indexing = 1, + mcsdk_svc_indexer_state_stopping = 2, + mcsdk_svc_indexer_state_stopped = 3 +} mcsdk_svc_indexer_state; + +typedef enum mcsdk_svc_indexer_sync_type { + mcsdk_svc_indexer_sync_type_all = 0, + mcsdk_svc_indexer_sync_type_local = 1, + mcsdk_svc_indexer_sync_type_rebuild = 2, + mcsdk_svc_indexer_sync_type_sources = 3 +} mcsdk_svc_indexer_sync_type; typedef enum mcsdk_replay_gain_mode { mcsdk_replay_gain_mode_disabled = 0, @@ -214,6 +228,7 @@ mcsdk_define_handle(mcsdk_track_list); mcsdk_define_handle(mcsdk_track_list_editor); mcsdk_define_handle(mcsdk_svc_metadata); mcsdk_define_handle(mcsdk_svc_playback); +mcsdk_define_handle(mcsdk_svc_indexer); mcsdk_define_handle(mcsdk_prefs); mcsdk_define_handle(mcsdk_audio_buffer); mcsdk_define_handle(mcsdk_audio_buffer_provider); @@ -238,6 +253,12 @@ typedef struct mcsdk_audio_player_callbacks { void (*on_mixpoint)(mcsdk_audio_player p, int id, double time); } mcsdk_audio_player_callbacks; +typedef struct mcsdk_svc_indexer_callbacks { + void (*on_started)(mcsdk_svc_indexer i); + void (*on_finished)(mcsdk_svc_indexer i, int tracks_processed); + void (*on_progress)(mcsdk_svc_indexer i, int tracks_processed); +} mcsdk_svc_indexer_callbacks; + typedef struct mcsdk_audio_player_gain { float preamp; float gain; @@ -252,6 +273,7 @@ typedef struct mcsdk_audio_player_gain { typedef struct mcsdk_context { mcsdk_svc_metadata metadata; mcsdk_svc_playback playback; + mcsdk_svc_indexer indexer; mcsdk_prefs preferences; mcsdk_internal internal; } mcsdk_context; @@ -596,4 +618,18 @@ mcsdk_export bool mcsdk_audio_player_has_capability(mcsdk_audio_player ap, mcsdk mcsdk_export mcsdk_audio_player_gain mcsdk_audio_player_get_default_gain(); mcsdk_export void mcsdk_audio_player_release(mcsdk_audio_player ap, mcsdk_audio_player_release_mode mode); +/* + * IIndexer + */ + +mcsdk_export void mcsdk_svc_indexer_add_path(mcsdk_svc_indexer in, const char* path); +mcsdk_export void mcsdk_svc_indexer_remove_path(mcsdk_svc_indexer in, const char* path); +mcsdk_export int mcsdk_svc_indexer_get_paths_count(mcsdk_svc_indexer in); +mcsdk_export int mcsdk_svc_indexer_get_paths_at(mcsdk_svc_indexer in, int index, char* dst, int len); +mcsdk_export void mcsdk_svc_indexer_schedule(mcsdk_svc_indexer in, mcsdk_svc_indexer_sync_type type); +mcsdk_export void mcsdk_svc_indexer_stop(mcsdk_svc_indexer in); +mcsdk_export mcsdk_svc_indexer_state mcsdk_svc_indexer_get_state(mcsdk_svc_indexer in); +mcsdk_export void mcsdk_svc_indexer_add_callbacks(mcsdk_svc_indexer in, mcsdk_svc_indexer_callbacks* cb); +mcsdk_export void mcsdk_svc_indexer_remove_callbacks(mcsdk_svc_indexer in, mcsdk_svc_indexer_callbacks* cb); + #endif \ No newline at end of file