Added C support for Stream and Player -- low-level playback is now

possible.
This commit is contained in:
casey langen 2020-01-29 19:18:15 -08:00
parent f2a9fe6791
commit 68853eb5a8
11 changed files with 441 additions and 180 deletions

View File

@ -35,8 +35,7 @@
#pragma once
#include <core/config.h>
#include <core/io/DataStreamFactory.h>
#include <core/audio/Buffer.h>
#include <core/sdk/IBuffer.h>
#include <core/sdk/IDecoder.h>
#include <core/sdk/IDSP.h>
#include <core/sdk/IDecoderFactory.h>
@ -47,18 +46,15 @@ namespace musik { namespace core { namespace audio {
class IStream {
public:
typedef enum {
NoDSP = 1
} Options;
virtual Buffer* GetNextProcessedOutputBuffer() = 0;
virtual void OnBufferProcessedByPlayer(Buffer* buffer) = 0;
virtual musik::core::sdk::IBuffer* GetNextProcessedOutputBuffer() = 0;
virtual void OnBufferProcessedByPlayer(musik::core::sdk::IBuffer* buffer) = 0;
virtual double SetPosition(double seconds) = 0;
virtual double GetDuration() = 0;
virtual bool OpenStream(std::string uri) = 0;
virtual void Interrupt() = 0;
virtual int GetCapabilities() = 0;
virtual bool Eof() = 0;
virtual void Release() = 0;
};
typedef std::shared_ptr<IStream> IStreamPtr;

View File

@ -124,6 +124,7 @@ Player::Player(
EventListener *listener,
Gain gain)
: state(Player::Idle)
, stream(Stream::Create())
, url(url)
, currentPosition(0)
, output(output)
@ -287,9 +288,7 @@ void musik::core::audio::playerThreadLoop(Player* player) {
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
#endif
player->stream = Stream::Create();
Buffer* buffer = nullptr;
IBuffer* buffer = nullptr;
float gain = player->gain.preamp * player->gain.gain;
if (gain > 1.0f && player->gain.peakValid) {

View File

@ -53,7 +53,7 @@ namespace musik { namespace core { namespace audio {
class Player : public musik::core::sdk::IBufferProvider {
public:
enum DestroyMode { Drain, NoDrain };
enum DestroyMode { Drain = 0, NoDrain = 1 };
struct Gain {
Gain() {
@ -168,6 +168,7 @@ namespace musik { namespace core { namespace audio {
DestroyMode destroyMode;
Gain gain;
int pendingBufferCount;
bool threadFinished;
FftContext* fftContext;
};

View File

@ -36,7 +36,6 @@
#include "Stream.h"
#include "Streams.h"
#include <core/sdk/constants.h>
#include <core/debug.h>
using namespace musik::core::audio;
@ -47,7 +46,7 @@ static std::string TAG = "Stream";
#define MIN_BUFFER_COUNT 30
Stream::Stream(int samplesPerChannel, double bufferLengthSeconds, unsigned int options)
Stream::Stream(int samplesPerChannel, double bufferLengthSeconds, StreamFlags options)
: options(options)
, samplesPerChannel(samplesPerChannel)
, bufferLengthSeconds(bufferLengthSeconds)
@ -60,7 +59,7 @@ Stream::Stream(int samplesPerChannel, double bufferLengthSeconds, unsigned int o
, done(false)
, capabilities(0)
, rawBuffer(nullptr) {
if ((this->options & NoDSP) == 0) {
if (((int) this->options & (int) StreamFlags::NoDSP) == 0) {
dsps = streams::GetDspPlugins();
}
@ -81,10 +80,14 @@ Stream::~Stream() {
}
}
IStreamPtr Stream::Create(int samplesPerChannel, double bufferLengthSeconds, unsigned int options) {
IStreamPtr Stream::Create(int samplesPerChannel, double bufferLengthSeconds, StreamFlags options) {
return IStreamPtr(new Stream(samplesPerChannel, bufferLengthSeconds, options));
}
IStream* Stream::CreateUnmanaged(int samplesPerChannel, double bufferLengthSeconds, StreamFlags options) {
return new Stream(samplesPerChannel, bufferLengthSeconds, options);
}
double Stream::SetPosition(double requestedSeconds) {
double actualSeconds = this->decoder->SetPosition(requestedSeconds);
@ -146,8 +149,8 @@ void Stream::Interrupt() {
}
}
void Stream::OnBufferProcessedByPlayer(Buffer* buffer) {
this->recycledBuffers.push_back(buffer);
void Stream::OnBufferProcessedByPlayer(IBuffer* buffer) {
this->recycledBuffers.push_back((Buffer*) buffer);
}
bool Stream::GetNextBufferFromDecoder() {
@ -188,7 +191,7 @@ inline Buffer* Stream::GetEmptyBuffer() {
return nullptr;
}
Buffer* Stream::GetNextProcessedOutputBuffer() {
IBuffer* Stream::GetNextProcessedOutputBuffer() {
this->RefillInternalBuffers();
/* in the normal case we have buffers available in the filled queue. */

View File

@ -40,6 +40,7 @@
#include <core/audio/IStream.h>
#include <core/sdk/IDecoder.h>
#include <core/sdk/IDSP.h>
#include <core/sdk/constants.h>
#include <deque>
#include <list>
@ -49,27 +50,38 @@ namespace musik { namespace core { namespace audio {
class Stream : public IStream {
using IDSP = musik::core::sdk::IDSP;
using IDecoder = musik::core::sdk::IDecoder;
using IBuffer = musik::core::sdk::IBuffer;
using StreamFlags = musik::core::sdk::StreamFlags;
public:
static IStreamPtr Create(
int samplesPerChannel = 2048,
double bufferLengthSeconds = 5,
unsigned int options = 0);
StreamFlags options = StreamFlags::None);
static IStream* CreateUnmanaged(
int samplesPerChannel = 2048,
double bufferLengthSeconds = 5,
StreamFlags options = StreamFlags::None);
private:
Stream(int samplesPerChannel, double bufferLengthSeconds, unsigned int options);
Stream(
int samplesPerChannel,
double bufferLengthSeconds,
StreamFlags options);
public:
virtual ~Stream();
virtual Buffer* GetNextProcessedOutputBuffer() override;
virtual void OnBufferProcessedByPlayer(Buffer* buffer) override;
virtual IBuffer* GetNextProcessedOutputBuffer() override;
virtual void OnBufferProcessedByPlayer(IBuffer* buffer) override;
virtual double SetPosition(double seconds) override;
virtual double GetDuration() override;
virtual bool OpenStream(std::string uri) override;
virtual void Interrupt() override;
virtual int GetCapabilities() override;
virtual bool Eof() override { return this->done; }
virtual void Release() override { delete this; }
private:
bool GetNextBufferFromDecoder();
@ -94,7 +106,7 @@ namespace musik { namespace core { namespace audio {
long decoderSamplesRemain;
uint64_t decoderPosition;
unsigned int options;
musik::core::sdk::StreamFlags options;
int samplesPerChannel;
long samplesPerBuffer;
int bufferCount;

View File

@ -57,9 +57,16 @@
#include <core/sdk/IStreamingEncoder.h>
#include <core/sdk/IDevice.h>
#include <core/sdk/IOutput.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;
using namespace musik::core::audio;
#define ENV musik::core::plugin::Environment()
@ -84,13 +91,12 @@ using namespace musik::core::sdk;
#define DEVICE(x) reinterpret_cast<IDevice*>(x.opaque)
#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 RELEASE(x, type) if (mcsdk_handle_ok(x)) { type(x)->Release(); x.opaque = nullptr; }
/*
*
* IResource
*
*/
mcsdk_export int64_t mcsdk_resource_get_id(mcsdk_resource r) {
@ -106,9 +112,7 @@ mcsdk_export void mcsdk_resource_release(mcsdk_resource r) {
}
/*
*
* IValue
*
*/
mcsdk_export size_t mcsdk_value_get_value(mcsdk_value v, char* dst, size_t size) {
@ -120,9 +124,7 @@ mcsdk_export void mcsdk_value_release(mcsdk_value v) {
}
/*
*
* IValueList
*
*/
mcsdk_export size_t mcsdk_value_list_count(mcsdk_value_list vl) {
@ -138,9 +140,7 @@ mcsdk_export void mcsdk_value_list_release(mcsdk_value_list vl) {
}
/*
*
* IMap
*
*/
mcsdk_export int mcsdk_map_get_string(mcsdk_map m, const char* key, char* dst, int size) {
@ -164,9 +164,7 @@ mcsdk_export void mcsdk_map_release(mcsdk_map m) {
}
/*
*
* IMapList
*
*/
mcsdk_export size_t mcsdk_map_list_get_count(mcsdk_map_list ml) {
@ -182,9 +180,7 @@ mcsdk_export void mcsdk_map_list_release(mcsdk_map_list ml) {
}
/*
*
* ITrack
*
*/
mcsdk_export void mcsdk_track_retain(mcsdk_track t) {
@ -200,9 +196,7 @@ mcsdk_export void mcsdk_track_release(mcsdk_track t) {
}
/*
*
* ITrackList
*
*/
mcsdk_export size_t mcsdk_track_list_get_count(mcsdk_track_list tl) {
@ -226,9 +220,7 @@ mcsdk_export void mcsdk_track_list_release(mcsdk_track_list tl) {
}
/*
*
* ITrackListEditor
*
*/
mcsdk_export bool mcsdk_track_list_editor_insert(mcsdk_track_list_editor tle, int64_t id, size_t index) {
@ -264,9 +256,7 @@ mcsdk_export void mcsdk_track_list_editor_release(mcsdk_track_list_editor tle) {
}
/*
*
* IMetadataProxy
*
*/
mcsdk_export mcsdk_track_list mcsdk_svc_metadata_query_tracks(mcsdk_svc_metadata mp, const char* keyword, int limit, int offset) {
@ -358,9 +348,7 @@ mcsdk_export void mcsdk_svc_metadata_release(mcsdk_svc_metadata mp) {
}
/*
*
* IPlaybackService
*
*/
mcsdk_export void mcsdk_svc_playback_play_at(mcsdk_svc_playback pb, size_t index) {
@ -480,9 +468,7 @@ mcsdk_export mcsdk_track_list mcsdk_svc_playback_clone(mcsdk_svc_playback pb) {
}
/*
*
* IPreferences
*
*/
mcsdk_export bool mcsdk_prefs_get_bool(mcsdk_prefs p, const char* key, bool defaultValue) {
@ -522,9 +508,7 @@ mcsdk_export void mcsdk_prefs_release(mcsdk_prefs p) {
}
/*
*
* IDataStream
*
*/
mcsdk_export bool mcsdk_data_stream_open(mcsdk_data_stream ds, const char *uri, mcsdk_stream_open_flags flags) {
@ -592,9 +576,7 @@ mcsdk_export void mcsdk_data_stream_release(mcsdk_data_stream ds) {
}
/*
*
* IBuffer
*
*/
mcsdk_export long mcsdk_audio_buffer_get_sample_rate(mcsdk_audio_buffer ab) {
@ -634,9 +616,7 @@ mcsdk_export void mcsdk_audio_buffer_release(mcsdk_audio_buffer ab) {
}
/*
*
* IBufferProvider
*
*/
mcsdk_export void mcsdk_audio_buffer_provider_notify_processed(mcsdk_audio_buffer_provider abp, mcsdk_audio_buffer ab) {
@ -644,9 +624,7 @@ mcsdk_export void mcsdk_audio_buffer_provider_notify_processed(mcsdk_audio_buffe
}
/*
*
* IDevice
*
*/
mcsdk_export const char* mcsdk_device_get_name(mcsdk_device d) {
@ -662,9 +640,7 @@ mcsdk_export void mcsdk_device_release(mcsdk_device d) {
}
/*
*
* IDeviceList
*
*/
mcsdk_export size_t mcsdk_device_list_get_count(mcsdk_device_list dl) {
@ -679,69 +655,64 @@ mcsdk_export void mcsdk_device_list_release(mcsdk_device_list dl) {
RELEASE(dl, DEVICELIST);
}
/*
*
* IOutput
*
*/
mcsdk_export void mcsdk_output_pause(mcsdk_output o) {
mcsdk_export void mcsdk_audio_output_pause(mcsdk_audio_output o) {
OUTPUT(o)->Pause();
}
mcsdk_export void mcsdk_output_resume(mcsdk_output o) {
mcsdk_export void mcsdk_audio_output_resume(mcsdk_audio_output o) {
OUTPUT(o)->Resume();
}
mcsdk_export void mcsdk_output_set_volume(mcsdk_output o, double volume) {
mcsdk_export void mcsdk_audio_output_set_volume(mcsdk_audio_output o, double volume) {
OUTPUT(o)->SetVolume(volume);
}
mcsdk_export double mcsdk_output_get_volume(mcsdk_output o) {
mcsdk_export double mcsdk_audio_output_get_volume(mcsdk_audio_output o) {
return OUTPUT(o)->GetVolume();
}
mcsdk_export void mcsdk_output_stop(mcsdk_output o) {
mcsdk_export void mcsdk_audio_output_stop(mcsdk_audio_output o) {
OUTPUT(o)->Stop();
}
mcsdk_export int mcsdk_output_play(mcsdk_output o, mcsdk_audio_buffer ab, mcsdk_audio_buffer_provider abp) {
mcsdk_export int mcsdk_audio_output_play(mcsdk_audio_output o, mcsdk_audio_buffer ab, mcsdk_audio_buffer_provider abp) {
return OUTPUT(o)->Play(BUFFER(ab), BUFFERPROVIDER(abp));
}
mcsdk_export void mcsdk_output_drain(mcsdk_output o) {
mcsdk_export void mcsdk_audio_output_drain(mcsdk_audio_output o) {
OUTPUT(o)->Drain();
}
mcsdk_export double mcsdk_output_get_latency(mcsdk_output o) {
mcsdk_export double mcsdk_audio_output_get_latency(mcsdk_audio_output o) {
return OUTPUT(o)->Latency();
}
mcsdk_export const char* mcsdk_output_get_name(mcsdk_output o) {
mcsdk_export const char* mcsdk_audio_output_get_name(mcsdk_audio_output o) {
return OUTPUT(o)->Name();
}
mcsdk_export mcsdk_device_list mcsdk_output_get_device_list(mcsdk_output o) {
mcsdk_export mcsdk_device_list mcsdk_audio_output_get_device_list(mcsdk_audio_output o) {
return mcsdk_device_list { OUTPUT(o)->GetDeviceList() };
}
mcsdk_export bool mcsdk_output_set_default_device(mcsdk_output o, const char* device_id) {
mcsdk_export bool mcsdk_audio_output_set_default_device(mcsdk_audio_output o, const char* device_id) {
return OUTPUT(o)->SetDefaultDevice(device_id);
}
mcsdk_export mcsdk_device mcsdk_output_get_default_device(mcsdk_output o) {
mcsdk_export mcsdk_device mcsdk_audio_output_get_default_device(mcsdk_audio_output o) {
return mcsdk_device { OUTPUT(o)->GetDefaultDevice() };
}
mcsdk_export void mcsdk_output_release(mcsdk_output o) {
mcsdk_export void mcsdk_audio_output_release(mcsdk_audio_output o) {
RELEASE(o, OUTPUT);
}
/*
*
* IDecoder
*
*/
mcsdk_export double mcsdk_decoder_set_position(mcsdk_decoder d, double seconds) {
@ -769,9 +740,7 @@ mcsdk_export void mcsdk_decoder_release(mcsdk_decoder d) {
}
/*
*
* IEncoder
*
*/
mcsdk_export void mcsdk_encoder_release(mcsdk_encoder e) {
@ -787,9 +756,7 @@ mcsdk_export mcsdk_encoder_type mcsdk_encoder_get_type(mcsdk_encoder e) {
}
/*
*
* IBlockingEncoder
*
*/
mcsdk_export bool mcsdk_blocking_encoder_initialize(mcsdk_blocking_encoder be, mcsdk_data_stream out, size_t rate, size_t channels, size_t bitrate) {
@ -809,9 +776,7 @@ mcsdk_export void mcsdk_blocking_encoder_release(mcsdk_blocking_encoder be, mcsd
}
/*
*
* IStreamingEncoder
*
*/
mcsdk_export bool mcsdk_streaming_encoder_initialize(mcsdk_streaming_encoder se, size_t rate, size_t channels, size_t bitrate) {
@ -835,9 +800,7 @@ mcsdk_export void mcsdk_streaming_encoder_release(mcsdk_streaming_encoder se, mc
}
/*
*
* IDebug
*
*/
mcsdk_export void mcsdk_debug_verbose(const char* tag, const char* message) {
@ -857,9 +820,7 @@ mcsdk_export void mcsdk_debug_error(const char* tag, const char* message) {
}
/*
*
* IEnvironment (TODO)
*
* IEnvironment
*/
mcsdk_export size_t mcsdk_env_get_path(mcsdk_path_type type, char* dst, int size) {
@ -890,12 +851,12 @@ mcsdk_export size_t mcsdk_env_get_output_count() {
return ENV.GetOutputCount();
}
mcsdk_export mcsdk_output mcsdk_env_get_output_at_index(size_t index) {
return mcsdk_output { ENV.GetOutputAtIndex(index) };
mcsdk_export mcsdk_audio_output mcsdk_env_get_output_at_index(size_t index) {
return mcsdk_audio_output { ENV.GetOutputAtIndex(index) };
}
mcsdk_export mcsdk_output mcsdk_env_get_output_with_name(const char* name) {
return mcsdk_output { ENV.GetOutputWithName(name) };
mcsdk_export mcsdk_audio_output mcsdk_env_get_output_with_name(const char* name) {
return mcsdk_audio_output { ENV.GetOutputWithName(name) };
}
mcsdk_export mcsdk_replay_gain_mode mcsdk_env_get_replay_gain_mode() {
@ -934,12 +895,12 @@ mcsdk_export void mcsdk_env_reload_playback_output() {
ENV.ReloadPlaybackOutput();
}
mcsdk_export void mcsdk_env_set_default_output(mcsdk_output output) {
mcsdk_export void mcsdk_env_set_default_output(mcsdk_audio_output output) {
ENV.SetDefaultOutput(OUTPUT(output));
}
mcsdk_export mcsdk_output mcsdk_env_get_default_output() {
return mcsdk_output { ENV.GetDefaultOutput() };
mcsdk_export mcsdk_audio_output mcsdk_env_get_default_output() {
return mcsdk_audio_output { ENV.GetDefaultOutput() };
}
mcsdk_export mcsdk_transport_type mcsdk_env_get_transport_type() {
@ -950,3 +911,258 @@ mcsdk_export void mcsdk_env_set_transport_type(mcsdk_transport_type type) {
ENV.SetTransportType((TransportType) type);
}
/*
* IStream
*/
mcsdk_export mcsdk_audio_stream mcsdk_audio_stream_create(int samples_per_channel, double buffer_length_seconds, mcsdk_audio_stream_flags options) {
return mcsdk_audio_stream { Stream::CreateUnmanaged(samples_per_channel, buffer_length_seconds, (StreamFlags) options) };
}
mcsdk_export mcsdk_audio_buffer mcsdk_audio_stream_get_next_buffer(mcsdk_audio_stream as) {
return mcsdk_audio_buffer { AUDIOSTREAM(as)->GetNextProcessedOutputBuffer() };
}
mcsdk_export void mcsdk_audio_stream_recycle_buffer(mcsdk_audio_stream as, mcsdk_audio_buffer ab) {
AUDIOSTREAM(as)->OnBufferProcessedByPlayer(BUFFER(ab));
}
mcsdk_export double mcsdk_audio_stream_set_position(mcsdk_audio_stream as, double seconds) {
return AUDIOSTREAM(as)->SetPosition(seconds);
}
mcsdk_export double mcsdk_audio_stream_get_duration(mcsdk_audio_stream as) {
return AUDIOSTREAM(as)->GetDuration();
}
mcsdk_export bool mcsdk_audio_stream_open_uri(mcsdk_audio_stream as, const char* uri) {
return AUDIOSTREAM(as)->OpenStream(uri);
}
mcsdk_export void mcsdk_audio_stream_interrupt(mcsdk_audio_stream as) {
AUDIOSTREAM(as)->Interrupt();
}
mcsdk_export mcsdk_stream_capability mcsdk_audio_stream_get_capabilities(mcsdk_audio_stream as) {
return (mcsdk_stream_capability) AUDIOSTREAM(as)->GetCapabilities();
}
mcsdk_export bool mcsdk_audio_stream_is_eof(mcsdk_audio_stream as) {
return AUDIOSTREAM(as)->Eof();
}
mcsdk_export void mcsdk_audio_stream_release(mcsdk_audio_stream as) {
RELEASE(as, AUDIOSTREAM);
}
/*
* 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;
virtual void OnPlayerPrepared(Player *player) {
std::unique_lock<std::mutex> lock(this->context->event_mutex);
for (auto c : callbacks) {
if (c->on_prepared) {
c->on_prepared(mcsdk_audio_player { context });
}
}
}
virtual void OnPlayerStarted(Player *player) {
std::unique_lock<std::mutex> lock(this->context->event_mutex);
for (auto c : callbacks) {
if (c->on_started) {
c->on_started(mcsdk_audio_player { context });
}
}
}
virtual void OnPlayerAlmostEnded(Player *player) {
std::unique_lock<std::mutex> lock(this->context->event_mutex);
for (auto c : callbacks) {
if (c->on_almost_ended) {
c->on_almost_ended(mcsdk_audio_player { context });
}
}
}
virtual void OnPlayerFinished(Player *player) {
std::unique_lock<std::mutex> lock(this->context->event_mutex);
for (auto c : callbacks) {
if (c->on_finished) {
c->on_finished(mcsdk_audio_player { context });
}
}
}
virtual void OnPlayerError(Player *player) {
std::unique_lock<std::mutex> lock(this->context->event_mutex);
for (auto c : callbacks) {
if (c->on_error) {
c->on_error(mcsdk_audio_player { context });
}
}
}
virtual void OnPlayerDestroying(Player *player) {
std::unique_lock<std::mutex> lock(this->context->event_mutex);
for (auto c : callbacks) {
if (c->on_destroying) {
c->on_destroying(mcsdk_audio_player { context });
}
}
this->context->player_finished = true;
this->context->finished_condition.notify_all();
}
virtual void OnPlayerMixPoint(Player *player, int id, double time) {
std::unique_lock<std::mutex> lock(this->context->event_mutex);
for (auto c : callbacks) {
if (c->on_mixpoint) {
c->on_mixpoint(mcsdk_audio_player { context }, id, time);
}
}
}
};
#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;
playerGain.preamp = gain.preamp;
playerGain.peak = gain.peak;
playerGain.peakValid = gain.peakValid;
auto callbackProxy = new mcsdk_audio_player_callback_proxy();
mcsdk_internal_player_context* playerContext = new mcsdk_internal_player_context();
playerContext->event_listener = callbackProxy;
playerContext->player_finished = false;
playerContext->output = std::shared_ptr<IOutput>(OUTPUT(output), [](IOutput*){});
playerContext->player = Player::Create(
url,
playerContext->output,
Player::DestroyMode::Drain,
playerContext->event_listener,
playerGain);
callbackProxy->context = playerContext;
if (callbacks) {
callbackProxy->callbacks.insert(callbacks);
}
return mcsdk_audio_player { playerContext };;
}
mcsdk_export int mcsdk_audio_player_get_url(mcsdk_audio_player ap, char* dst, int size) {
mcsdk_internal_player_context* context = PLAYER(ap);
std::unique_lock<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
return (int) CopyString(context->player->GetUrl(), dst, size);
}
return (int) CopyString("", dst, size);
}
mcsdk_export void mcsdk_audio_player_detach(mcsdk_audio_player ap, mcsdk_audio_player_callbacks* callbacks) {
mcsdk_internal_player_context* 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);
auto it = proxy->callbacks.find(callbacks);
if (it != proxy->callbacks.end()) {
proxy->callbacks.erase(it);
}
}
}
mcsdk_export void mcsdk_audio_player_attach(mcsdk_audio_player ap, mcsdk_audio_player_callbacks* callbacks) {
mcsdk_internal_player_context* 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);
}
}
mcsdk_export void mcsdk_audio_player_play(mcsdk_audio_player ap) {
mcsdk_internal_player_context* context = PLAYER(ap);
std::unique_lock<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
context->player->Play();
}
}
mcsdk_export double mcsdk_audio_player_get_position(mcsdk_audio_player ap) {
mcsdk_internal_player_context* context = PLAYER(ap);
std::unique_lock<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
return context->player->GetPosition();
}
return 0.0;
}
mcsdk_export void mcsdk_audio_player_set_position(mcsdk_audio_player ap, double seconds) {
mcsdk_internal_player_context* context = PLAYER(ap);
std::unique_lock<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
context->player->SetPosition(seconds);
}
}
mcsdk_export double mcsdk_audio_player_get_duration(mcsdk_audio_player ap) {
mcsdk_internal_player_context* context = PLAYER(ap);
std::unique_lock<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
return context->player->GetDuration();
}
return 0.0;
}
mcsdk_export void mcsdk_audio_player_add_mix_point(mcsdk_audio_player ap, int id, double time) {
mcsdk_internal_player_context* context = PLAYER(ap);
std::unique_lock<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
context->player->AddMixPoint(id, time);
}
}
mcsdk_export bool mcsdk_audio_player_has_capability(mcsdk_audio_player ap, mcsdk_stream_capability capability) {
mcsdk_internal_player_context* context = PLAYER(ap);
std::unique_lock<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
return PLAYER(ap)->player->HasCapability((Capability) capability);
}
return false;
}
mcsdk_export void mcsdk_audio_player_release(mcsdk_audio_player ap, mcsdk_audio_player_release_mode mode) {
mcsdk_internal_player_context* context = PLAYER(ap);
{
std::unique_lock<std::mutex> lock(context->event_mutex);
if (!context->player_finished) {
context->player->Destroy((Player::DestroyMode) mode);
while (!context->player_finished) {
context->finished_condition.wait(lock);
}
}
}
delete context->event_listener;
delete context;
ap.opaque = nullptr;
}
mcsdk_export mcsdk_audio_player_gain mcsdk_audio_player_get_default_gain() {
return mcsdk_audio_player_gain { 1.0, 1.0, 0.0, false };
}

View File

@ -895,14 +895,14 @@ void Indexer::RunAnalyzers() {
}
if (!runningAnalyzers.empty()) {
audio::IStreamPtr stream = audio::Stream::Create(audio::IStream::NoDSP);
audio::IStreamPtr stream = audio::Stream::Create(2048, 2.0, StreamFlags::NoDSP);
if (stream) {
if (stream->OpenStream(track.Uri())) {
/* decode the stream quickly, passing to all analyzers */
audio::Buffer* buffer;
IBuffer* buffer;
while ((buffer = stream->GetNextProcessedOutputBuffer()) && !runningAnalyzers.empty()) {
PluginVector::iterator plugin = runningAnalyzers.begin();

View File

@ -51,17 +51,13 @@
#endif
/*
*
* version
*
*/
static const int mcsdk_version = 18;
/*
*
* constants
*
*/
typedef enum mcsdk_playback_state {
@ -87,12 +83,12 @@ typedef enum mcsdk_repeat_mode {
mcsdk_repeat_list = 2
} mcsdk_repeat_mode;
typedef enum mcsdk_output_code {
mcsdk_output_error_invalid_format = -4,
mcsdk_output_error_invalid_state = -3,
mcsdk_output_error_buffer_full = -2,
mcsdk_output_error_buffer_written = -1
} mcsdk_output_code;
typedef enum mcsdk_audio_output_code {
mcsdk_audio_output_error_invalid_format = -4,
mcsdk_audio_output_error_invalid_state = -3,
mcsdk_audio_output_error_buffer_full = -2,
mcsdk_audio_output_error_buffer_written = -1
} mcsdk_audio_output_code;
typedef enum mcsdk_time_change_mode {
mcsdk_time_change_mode_seek = 0,
@ -133,6 +129,11 @@ typedef enum mcsdk_stream_open_flags {
mcsdk_stream_open_flags_write = 2
} mcsdk_stream_open_flags;
typedef enum mcsdk_audio_stream_flags {
mcsdk_audio_stream_flags_none = 0,
mcsdk_audio_stream_flags_no_dsp = 1
} mcsdk_audio_stream_flags;
typedef enum mcsdk_resource_class {
mcsdk_resource_type_value = 0,
mcsdk_resource_type_map = 1
@ -143,6 +144,11 @@ typedef enum mcsdk_encoder_type {
mcsdk_encoder_type_streaming = 1
} mcsdk_encoder_type;
typedef enum mcsdk_audio_player_release_mode {
mcsdk_audio_player_release_mode_drain = 0,
mcsdk_audio_player_release_mode_no_drain = 1
} mcsdk_audio_player_release_mode;
static const size_t mcsdk_equalizer_band_count = 18;
static const size_t mcsdk_equalizer_bands[] = {
@ -182,9 +188,7 @@ static const char* mcsdk_track_field_source_id = "source_id";
static const char* mcsdk_track_field_external_id = "external_id";
/*
*
* types
*
*/
#define mcsdk_define_handle(x) \
@ -196,6 +200,8 @@ static const char* mcsdk_track_field_external_id = "external_id";
#define mcsdk_cast_handle(x) { x.opaque }
#define mcsdk_handle_equals(x, y) x.opaque == y.opaque
mcsdk_define_handle(mcsdk_internal);
mcsdk_define_handle(mcsdk_resource);
mcsdk_define_handle(mcsdk_value);
@ -213,16 +219,33 @@ mcsdk_define_handle(mcsdk_audio_buffer_provider);
mcsdk_define_handle(mcsdk_data_stream);
mcsdk_define_handle(mcsdk_device);
mcsdk_define_handle(mcsdk_device_list);
mcsdk_define_handle(mcsdk_output);
mcsdk_define_handle(mcsdk_audio_output);
mcsdk_define_handle(mcsdk_decoder);
mcsdk_define_handle(mcsdk_encoder);
mcsdk_define_handle(mcsdk_blocking_encoder);
mcsdk_define_handle(mcsdk_streaming_encoder);
mcsdk_define_handle(mcsdk_audio_stream);
mcsdk_define_handle(mcsdk_audio_player);
typedef struct mcsdk_audio_player_callbacks {
void (*on_prepared)(mcsdk_audio_player p);
void (*on_started)(mcsdk_audio_player p);
void (*on_almost_ended)(mcsdk_audio_player p);
void (*on_finished)(mcsdk_audio_player p);
void (*on_error)(mcsdk_audio_player p);
void (*on_destroying)(mcsdk_audio_player p);
void (*on_mixpoint)(mcsdk_audio_player p, int id, double time);
} mcsdk_audio_player_callbacks;
typedef struct mcsdk_audio_player_gain {
float preamp;
float gain;
float peak;
float peakValid;
} mcsdk_audio_player_gain;
/*
*
* instance context
*
*/
typedef struct mcsdk_context {
@ -238,9 +261,7 @@ mcsdk_export void mcsdk_set_plugin_context(mcsdk_context* context);
mcsdk_export bool mcsdk_is_plugin_context(mcsdk_context* context);
/*
*
* IResource
*
*/
mcsdk_export int64_t mcsdk_resource_get_id(mcsdk_resource r);
@ -248,18 +269,14 @@ mcsdk_export mcsdk_resource_class mcsdk_resource_get_class(mcsdk_resource r);
mcsdk_export void mcsdk_resource_release(mcsdk_resource r);
/*
*
* IValue
*
*/
mcsdk_export size_t mcsdk_value_get_value(mcsdk_value v, char* dst, size_t size);
mcsdk_export void mcsdk_value_release(mcsdk_value v);
/*
*
* IValueList
*
*/
mcsdk_export size_t mcsdk_value_list_count(mcsdk_value_list vl);
@ -267,9 +284,7 @@ mcsdk_export mcsdk_value mcsdk_value_list_get_at(mcsdk_value_list vl, size_t ind
mcsdk_export void mcsdk_value_list_release(mcsdk_value_list vl);
/*
*
* IMap
*
*/
mcsdk_export int mcsdk_map_get_string(mcsdk_map m, const char* key, char* dst, int size);
@ -279,9 +294,7 @@ mcsdk_export double mcsdk_map_get_double(mcsdk_map m, const char* key, double de
mcsdk_export void mcsdk_map_release(mcsdk_map m);
/*
*
* IMapList
*
*/
mcsdk_export size_t mcsdk_map_list_get_count(mcsdk_map_list ml);
@ -289,9 +302,7 @@ mcsdk_export mcsdk_map mcsdk_map_list_get_at(mcsdk_map_list ml, size_t index);
mcsdk_export void mcsdk_map_list_release(mcsdk_map_list ml);
/*
*
* ITrack
*
*/
mcsdk_export void mcsdk_track_retain(mcsdk_track t);
@ -299,9 +310,7 @@ mcsdk_export int mcsdk_track_get_uri(mcsdk_track t, char* dst, int size);
mcsdk_export void mcsdk_track_release(mcsdk_track t);
/*
*
* ITrackList
*
*/
mcsdk_export size_t mcsdk_track_list_get_count(mcsdk_track_list tl);
@ -311,9 +320,7 @@ mcsdk_export mcsdk_track mcsdk_track_list_get_track_at(mcsdk_track_list tl, size
mcsdk_export void mcsdk_track_list_release(mcsdk_track_list tl);
/*
*
* ITrackListEditor
*
*/
mcsdk_export bool mcsdk_track_list_editor_insert(mcsdk_track_list_editor tle, int64_t id, size_t index);
@ -326,9 +333,7 @@ mcsdk_export void mcsdk_track_list_editor_shuffle(mcsdk_track_list_editor tle);
mcsdk_export void mcsdk_track_list_editor_release(mcsdk_track_list_editor tle);
/*
*
* IMetadataProxy
*
*/
mcsdk_export mcsdk_track_list mcsdk_svc_metadata_query_tracks(mcsdk_svc_metadata mp, const char* keyword, int limit, int offset);
@ -355,9 +360,7 @@ mcsdk_export size_t mcsdk_svc_metadata_remove_tracks_from_playlist(mcsdk_svc_met
mcsdk_export void mcsdk_svc_metadata_release(mcsdk_svc_metadata mp);
/*
*
* IPlaybackService
*
*/
mcsdk_export void mcsdk_svc_playback_play_at(mcsdk_svc_playback pb, size_t index);
@ -391,9 +394,7 @@ mcsdk_export void mcsdk_svc_playback_reload_output(mcsdk_svc_playback pb);
mcsdk_export mcsdk_track_list mcsdk_svc_playback_clone(mcsdk_svc_playback pb);
/*
*
* IPreferences
*
*/
mcsdk_export bool mcsdk_prefs_get_bool(mcsdk_prefs p, const char* key, bool defaultValue);
@ -407,9 +408,7 @@ mcsdk_export void mcsdk_prefs_save(mcsdk_prefs p);
mcsdk_export void mcsdk_prefs_release(mcsdk_prefs p);
/*
*
* IDataStream
*
*/
mcsdk_export bool mcsdk_data_stream_open(mcsdk_data_stream ds, const char *uri, mcsdk_stream_open_flags flags);
@ -430,9 +429,7 @@ mcsdk_export bool mcsdk_data_stream_can_prefetch(mcsdk_data_stream ds);
mcsdk_export void mcsdk_data_stream_release(mcsdk_data_stream ds);
/*
*
* IBuffer
*
*/
mcsdk_export long mcsdk_audio_buffer_get_sample_rate(mcsdk_audio_buffer ab);
@ -446,17 +443,13 @@ mcsdk_export long mcsdk_audio_buffer_get_byte_count(mcsdk_audio_buffer ab);
mcsdk_export void mcsdk_audio_buffer_release(mcsdk_audio_buffer ab);
/*
*
* IBufferProvider
*
*/
mcsdk_export void mcsdk_audio_buffer_provider_notify_processed(mcsdk_audio_buffer_provider abp, mcsdk_audio_buffer ab);
/*
*
* IDevice
*
*/
mcsdk_export const char* mcsdk_device_get_name(mcsdk_device d);
@ -464,9 +457,7 @@ mcsdk_export const char* mcsdk_device_get_id(mcsdk_device d);
mcsdk_export void mcsdk_device_release(mcsdk_device d);
/*
*
* IDeviceList
*
*/
mcsdk_export size_t mcsdk_device_list_get_count(mcsdk_device_list dl);
@ -474,29 +465,25 @@ mcsdk_export const mcsdk_device mcsdk_device_list_get_at(mcsdk_device_list dl, s
mcsdk_export void mcsdk_device_list_release(mcsdk_device_list dl);
/*
*
* IOutput
*
*/
mcsdk_export void mcsdk_output_pause(mcsdk_output o);
mcsdk_export void mcsdk_output_resume(mcsdk_output o);
mcsdk_export void mcsdk_output_set_volume(mcsdk_output o, double volume);
mcsdk_export double mcsdk_output_get_volume(mcsdk_output o);
mcsdk_export void mcsdk_output_stop(mcsdk_output o);
mcsdk_export int mcsdk_output_play(mcsdk_output o, mcsdk_audio_buffer ab, mcsdk_audio_buffer_provider abp);
mcsdk_export void mcsdk_output_drain(mcsdk_output o);
mcsdk_export double mcsdk_output_get_latency(mcsdk_output o);
mcsdk_export const char* mcsdk_output_get_name(mcsdk_output o);
mcsdk_export mcsdk_device_list mcsdk_output_get_device_list(mcsdk_output o);
mcsdk_export bool mcsdk_output_set_default_device(mcsdk_output o, const char* device_id);
mcsdk_export mcsdk_device mcsdk_output_get_default_device(mcsdk_output o);
mcsdk_export void mcsdk_output_release(mcsdk_output o);
mcsdk_export void mcsdk_audio_output_pause(mcsdk_audio_output o);
mcsdk_export void mcsdk_audio_output_resume(mcsdk_audio_output o);
mcsdk_export void mcsdk_audio_output_set_volume(mcsdk_audio_output o, double volume);
mcsdk_export double mcsdk_audio_output_get_volume(mcsdk_audio_output o);
mcsdk_export void mcsdk_audio_output_stop(mcsdk_audio_output o);
mcsdk_export int mcsdk_audio_output_play(mcsdk_audio_output o, mcsdk_audio_buffer ab, mcsdk_audio_buffer_provider abp);
mcsdk_export void mcsdk_audio_output_drain(mcsdk_audio_output o);
mcsdk_export double mcsdk_audio_output_get_latency(mcsdk_audio_output o);
mcsdk_export const char* mcsdk_audio_output_get_name(mcsdk_audio_output o);
mcsdk_export mcsdk_device_list mcsdk_audio_output_get_device_list(mcsdk_audio_output o);
mcsdk_export bool mcsdk_audio_output_set_default_device(mcsdk_audio_output o, const char* device_id);
mcsdk_export mcsdk_device mcsdk_audio_output_get_default_device(mcsdk_audio_output o);
mcsdk_export void mcsdk_audio_output_release(mcsdk_audio_output o);
/*
*
* IDecoder
*
*/
mcsdk_export double mcsdk_decoder_set_position(mcsdk_decoder d, double seconds);
@ -507,18 +494,14 @@ mcsdk_export bool mcsdk_decoder_is_eof(mcsdk_decoder d);
mcsdk_export void mcsdk_decoder_release(mcsdk_decoder d);
/*
*
* IEncoder
*
*/
mcsdk_export mcsdk_encoder_type mcsdk_encoder_get_type(mcsdk_encoder e);
mcsdk_export void mcsdk_encoder_release(mcsdk_encoder e);
/*
*
* IBlockingEncoder
*
*/
mcsdk_export bool mcsdk_blocking_encoder_initialize(mcsdk_blocking_encoder be, mcsdk_data_stream out, size_t rate, size_t channels, size_t bitrate);
@ -527,9 +510,7 @@ mcsdk_export void mcsdk_blocking_encoder_finalize(mcsdk_blocking_encoder be);
mcsdk_export void mcsdk_blocking_encoder_release(mcsdk_blocking_encoder be, mcsdk_encoder e);
/*
*
* IStreamingEncoder
*
*/
mcsdk_export bool mcsdk_streaming_encoder_initialize(mcsdk_streaming_encoder se, size_t rate, size_t channels, size_t bitrate);
@ -539,9 +520,7 @@ mcsdk_export void mcsdk_streaming_encoder_finalize(mcsdk_streaming_encoder se, c
mcsdk_export void mcsdk_streaming_encoder_release(mcsdk_streaming_encoder se, mcsdk_encoder e);
/*
*
* IDebug
*
*/
mcsdk_export void mcsdk_debug_verbose(const char* tag, const char* message);
@ -550,9 +529,7 @@ mcsdk_export void mcsdk_debug_warning(const char* tag, const char* message);
mcsdk_export void mcsdk_debug_error(const char* tag, const char* message);
/*
*
* IEnvironment
*
*/
mcsdk_export size_t mcsdk_env_get_path(mcsdk_path_type type, char* dst, int size);
@ -562,8 +539,8 @@ mcsdk_export mcsdk_encoder mcsdk_env_open_encoder(const char* type) ;
mcsdk_export mcsdk_audio_buffer mcsdk_env_create_audio_buffer(size_t samples, size_t rate, size_t channels);
mcsdk_export mcsdk_prefs mcsdk_env_open_preferences(const char* name);
mcsdk_export size_t mcsdk_env_get_output_count();
mcsdk_export mcsdk_output mcsdk_env_get_output_at_index(size_t index);
mcsdk_export mcsdk_output mcsdk_env_get_output_with_name(const char* name);
mcsdk_export mcsdk_audio_output mcsdk_env_get_output_at_index(size_t index);
mcsdk_export mcsdk_audio_output mcsdk_env_get_output_with_name(const char* name);
mcsdk_export mcsdk_replay_gain_mode mcsdk_env_get_replay_gain_mode();
mcsdk_export void mcsdk_env_set_replay_gain_mode(mcsdk_replay_gain_mode mode);
mcsdk_export float mcsdk_env_get_preamp_gain();
@ -573,9 +550,41 @@ mcsdk_export void mcsdk_env_set_equalizer_enabled(bool enabled);
mcsdk_export bool mcsdk_env_get_equalizer_band_values(double target[], size_t count);
mcsdk_export bool mcsdk_env_set_equalizer_band_values(double values[], size_t count);
mcsdk_export void mcsdk_env_reload_playback_output();
mcsdk_export void mcsdk_env_set_default_output(mcsdk_output output);
mcsdk_export mcsdk_output mcsdk_env_get_default_output();
mcsdk_export void mcsdk_env_set_default_output(mcsdk_audio_output output);
mcsdk_export mcsdk_audio_output mcsdk_env_get_default_output();
mcsdk_export mcsdk_transport_type mcsdk_env_get_transport_type();
mcsdk_export void mcsdk_env_set_transport_type(mcsdk_transport_type type);
/*
* IStream
*/
mcsdk_export mcsdk_audio_stream mcsdk_audio_stream_create(int samples_per_channel, double buffer_length_seconds, mcsdk_audio_stream_flags options);
mcsdk_export mcsdk_audio_buffer mcsdk_audio_stream_get_next_buffer(mcsdk_audio_stream as);
mcsdk_export void mcsdk_audio_stream_recycle_buffer(mcsdk_audio_stream as, mcsdk_audio_buffer ab);
mcsdk_export double mcsdk_audio_stream_set_position(mcsdk_audio_stream as, double seconds);
mcsdk_export double mcsdk_audio_stream_get_duration(mcsdk_audio_stream as);
mcsdk_export bool mcsdk_audio_stream_open_uri(mcsdk_audio_stream as, const char* uri);
mcsdk_export void mcsdk_audio_stream_interrupt(mcsdk_audio_stream as);
mcsdk_export mcsdk_stream_capability mcsdk_audio_stream_get_capabilities(mcsdk_audio_stream as);
mcsdk_export bool mcsdk_audio_stream_is_eof(mcsdk_audio_stream as);
mcsdk_export void mcsdk_audio_stream_release(mcsdk_audio_stream as);
/*
* Player
*/
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);
mcsdk_export int mcsdk_audio_player_get_url(mcsdk_audio_player ap, char* dst, int size);
mcsdk_export void mcsdk_audio_player_detach(mcsdk_audio_player ap, mcsdk_audio_player_callbacks* callbacks);
mcsdk_export void mcsdk_audio_player_attach(mcsdk_audio_player ap, mcsdk_audio_player_callbacks* callbacks);
mcsdk_export void mcsdk_audio_player_play(mcsdk_audio_player ap);
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_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_export bool mcsdk_audio_player_has_capability(mcsdk_audio_player ap, mcsdk_stream_capability capability);
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);
#endif

View File

@ -109,6 +109,11 @@ namespace musik {
Write = 2
};
enum class StreamFlags: int {
None = 0,
NoDSP = 1
};
static const size_t EqualizerBandCount = 18;
static const size_t EqualizerBands[] = {

View File

@ -1,5 +1,7 @@
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
@ -20,7 +22,7 @@ static void internal_sleep(int seconds) {
#ifdef WIN32
Sleep(seconds * 1000);
#else
usleep(1000000);
usleep(seconds * 1000000);
#endif
}
@ -54,19 +56,36 @@ static void test_decode_encode() {
printf("test_decode_encode: done.\n");
}
static void test_playback(mcsdk_context* context) {
static void test_low_level_playback() {
mcsdk_audio_player_gain gain = mcsdk_audio_player_get_default_gain();
mcsdk_audio_output output = mcsdk_env_get_default_output();
mcsdk_audio_player player = mcsdk_audio_player_create(INPUT_FILE, output, NULL, gain);
mcsdk_audio_output_set_volume(output, 0.75);
mcsdk_audio_output_resume(output);
mcsdk_audio_player_play(player);
printf("test_low_level_playback: playing for 5 seconds...\n");
for (int i = 0; i < 5; i++) {
internal_sleep(1);
printf(" %d\n", i + 1);
}
mcsdk_audio_player_release(player, mcsdk_audio_player_release_mode_no_drain);
mcsdk_audio_output_release(output);
printf("test_low_level_playback: done.\n");
}
static void test_high_level_playback(mcsdk_context* context) {
printf("test_playback: loading 'a day in the life' tracks\n");
mcsdk_track_list tl = mcsdk_svc_metadata_query_tracks(
context->metadata, "a day in the life", mcsdk_no_limit, mcsdk_no_offset);
mcsdk_svc_playback_play(context->playback, tl, 0);
mcsdk_track_list_release(tl);
printf("test_playback: playing for 5 seconds...\n");
printf("test_high_level_playback: playing for 5 seconds...\n");
for (int i = 0; i < 5; i++) {
internal_sleep(1);
printf(" %d\n", i + 1);
}
mcsdk_svc_playback_stop(context->playback);
printf("test_playback: done.\n");
printf("test_high_level_playback: done.\n");
}
static void test_metadata(mcsdk_context* context) {
@ -91,8 +110,9 @@ int main(int argc, char** argv) {
if (context) {
printf("main: context initialized\n");
test_metadata(context);
test_playback(context);
test_decode_encode(context);
test_low_level_playback();
test_high_level_playback(context);
test_decode_encode();
mcsdk_context_release(&context);
printf("main: context released\n");
}