Added support for the indexer.

This commit is contained in:
casey langen 2020-01-30 23:06:18 -08:00
parent de27613807
commit a38b797154
5 changed files with 193 additions and 38 deletions

View File

@ -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<mcsdk_context_internal*>(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<mcsdk_svc_indexer_context_internal*>(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;
}

View File

@ -37,8 +37,11 @@
#include <core/library/LibraryFactory.h>
#include <core/audio/PlaybackService.h>
#include <core/library/LocalMetadataProxy.h>
#include <core/library/IIndexer.h>
#include <string>
#include <thread>
#include <set>
using namespace musik;
using namespace musik::core;
@ -66,4 +69,21 @@ struct mcsdk_context_internal {
LocalMetadataProxy* metadata;
PlaybackService* playback;
std::shared_ptr<Preferences> preferences;
};
struct mcsdk_svc_indexer_callback_proxy;
struct mcsdk_svc_indexer_context_internal {
IIndexer* indexer;
mcsdk_svc_indexer_callback_proxy* callback_proxy;
std::set<mcsdk_svc_indexer_callbacks*> callbacks;
};
struct mcsdk_player_context_internal {
Player::EventListener* event_listener;
std::shared_ptr<IOutput> output;
std::mutex event_mutex;
std::condition_variable finished_condition;
Player* player;
bool player_finished;
};

View File

@ -59,13 +59,12 @@
#include <core/sdk/IStreamingEncoder.h>
#include <core/sdk/IDevice.h>
#include <core/sdk/IOutput.h>
#include <core/library/IIndexer.h>
#include <core/library/track/TrackList.h>
#include <core/audio/Stream.h>
#include <core/audio/Player.h>
#include <core/support/Common.h>
#include <set>
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<IDeviceList*>(x.opaque)
#define OUTPUT(x) reinterpret_cast<IOutput*>(x.opaque)
#define AUDIOSTREAM(x) reinterpret_cast<IStream*>(x.opaque)
#define PLAYER(x) reinterpret_cast<mcsdk_player_context_internal*>(x.opaque)
#define INDEXER(x) reinterpret_cast<mcsdk_svc_indexer_context_internal*>(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<IOutput> 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<mcsdk_audio_player_callbacks*> callbacks;
mcsdk_internal_player_context* context;
mcsdk_player_context_internal* context;
virtual void OnPlayerPrepared(Player *player) {
std::unique_lock<std::mutex> 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<mcsdk_internal_player_context*>(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<std::mutex> 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<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
auto proxy = reinterpret_cast<mcsdk_audio_player_callback_proxy*>(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<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
reinterpret_cast<mcsdk_audio_player_callback_proxy*>(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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<mcsdk_svc_indexer_context_internal*>(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<std::string> 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<std::string> 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);
}
}

View File

@ -46,17 +46,17 @@ namespace musik { namespace core {
sigslot::signal1<int> 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() { }

View File

@ -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