mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-15 12:41:38 +00:00
Added C support for Stream and Player -- low-level playback is now
possible.
This commit is contained in:
parent
f2a9fe6791
commit
68853eb5a8
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
}
|
@ -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();
|
||||
|
@ -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
|
@ -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[] = {
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user