mirror of
https://github.com/clangen/musikcube.git
synced 2025-01-30 15:32:37 +00:00
A bunch of small changes in preparation for release:
1. Finalized the initial `IEncoder` interface with a new `GetPreferences()` method so external parties can configure encoder operation. 2. Updated `IEnvironment` interface with a new `GetPreferences()` call so plugins (e.g. encoders) can be configured by other plugins. 3. Fixed sort order in plugin list to be alphabetical. 4. Ensure the main app depends on the "stockencoders" plugin in the Visual Studio solution.
This commit is contained in:
parent
51be0ccfb4
commit
e9f924fef8
@ -1,10 +1,11 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27004.2002
|
||||
VisualStudioVersion = 15.0.27004.2009
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "musikcube", "src\musikcube\musikcube.vcxproj", "{C7102EB1-7311-4B36-A7FF-89DD7F077FF9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{68AA481E-3CCE-440F-8CCE-69F1B371C89D} = {68AA481E-3CCE-440F-8CCE-69F1B371C89D}
|
||||
{8AD92D25-0921-44AB-BBEF-5244F5CFC6DA} = {8AD92D25-0921-44AB-BBEF-5244F5CFC6DA}
|
||||
{51C18730-DC48-411A-829D-F2B3B7AC4C97} = {51C18730-DC48-411A-829D-F2B3B7AC4C97}
|
||||
{3E30064E-B9C4-4690-8AC2-2C694176A319} = {3E30064E-B9C4-4690-8AC2-2C694176A319}
|
||||
{EBD2E652-AA1B-4B8B-8D03-CCECB9BF3304} = {EBD2E652-AA1B-4B8B-8D03-CCECB9BF3304}
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <core/io/DataStreamFactory.h>
|
||||
#include <core/audio/Buffer.h>
|
||||
#include <core/audio/Streams.h>
|
||||
|
||||
#include <core/support/Preferences.h>
|
||||
#include <core/library/LocalSimpleDataProvider.h>
|
||||
|
||||
#include <core/sdk/IIndexerNotifier.h>
|
||||
@ -104,6 +104,10 @@ static class Environment : public IEnvironment {
|
||||
return streams::GetEncoderForType(type);
|
||||
}
|
||||
|
||||
virtual IPreferences* GetPreferences(const char* name) override {
|
||||
return Preferences::Unmanaged(name ? name : std::string());
|
||||
}
|
||||
|
||||
virtual IBuffer* GetBuffer(size_t samples, size_t rate = 44100, size_t channels = 2) override {
|
||||
musik::core::audio::Buffer* buffer = new Buffer();
|
||||
buffer->SetChannels(2);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "IBuffer.h"
|
||||
#include "IPreferences.h"
|
||||
#include <stddef.h>
|
||||
|
||||
namespace musik { namespace core { namespace sdk {
|
||||
@ -46,6 +47,7 @@ namespace musik { namespace core { namespace sdk {
|
||||
virtual int Encode(const IBuffer* pcm, char** data) = 0;
|
||||
virtual int Flush(char** data) = 0;
|
||||
virtual void Finalize(const char* uri) = 0;
|
||||
virtual IPreferences* GetPreferences() = 0;
|
||||
};
|
||||
|
||||
} } }
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "IDataStream.h"
|
||||
#include "IDecoder.h"
|
||||
#include "IEncoder.h"
|
||||
#include "IPreferences.h"
|
||||
|
||||
namespace musik { namespace core { namespace sdk {
|
||||
|
||||
@ -48,6 +49,7 @@ namespace musik { namespace core { namespace sdk {
|
||||
virtual IDecoder* GetDecoder(IDataStream* stream) = 0;
|
||||
virtual IEncoder* GetEncoder(const char* type) = 0;
|
||||
virtual IBuffer* GetBuffer(size_t samples, size_t rate = 44100, size_t channels = 2) = 0;
|
||||
virtual IPreferences* GetPreferences(const char* name) = 0;
|
||||
};
|
||||
|
||||
} } }
|
||||
|
@ -38,6 +38,8 @@ namespace musik { namespace core { namespace sdk {
|
||||
|
||||
class IPreferences {
|
||||
public:
|
||||
virtual void Release() = 0;
|
||||
|
||||
virtual bool GetBool(const char* key, bool defaultValue = false) = 0;
|
||||
virtual int GetInt(const char* key, int defaultValue = 0) = 0;
|
||||
virtual double GetDouble(const char* key, double defaultValue = 0.0f) = 0;
|
||||
|
@ -63,13 +63,11 @@ static FILE* openFile(const std::string& fn, const std::string& mode) {
|
||||
}
|
||||
|
||||
static std::string fileToString(const std::string& fn) {
|
||||
FILE* f = openFile(fn, "rb");
|
||||
std::string result;
|
||||
|
||||
if (!f) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (fn.size()) {
|
||||
FILE* f = openFile(fn, "rb");
|
||||
if (f) {
|
||||
fseek(f, 0, SEEK_END);
|
||||
long len = ftell(f);
|
||||
rewind(f);
|
||||
@ -82,6 +80,8 @@ static std::string fileToString(const std::string& fn) {
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -131,6 +131,14 @@ std::shared_ptr<Preferences> Preferences::ForPlugin(const std::string& pluginNam
|
||||
return pluginCache[name];
|
||||
}
|
||||
|
||||
musik::core::sdk::IPreferences* Preferences::Unmanaged(const std::string& name) {
|
||||
if (!name.size()) {
|
||||
return new Preferences(name, ModeTransient);
|
||||
}
|
||||
|
||||
return Preferences::ForPlugin("unmanaged_" + name).get();
|
||||
}
|
||||
|
||||
std::shared_ptr<Preferences> Preferences::ForComponent(
|
||||
const std::string& c, Preferences::Mode mode)
|
||||
{
|
||||
@ -169,6 +177,12 @@ Preferences::~Preferences() {
|
||||
}
|
||||
}
|
||||
|
||||
void Preferences::Release() {
|
||||
if (this->mode == ModeTransient) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
#define RETURN_VALUE(defaultValue) \
|
||||
auto it = json.find(key); \
|
||||
if (it == json.end()) { \
|
||||
@ -242,8 +256,9 @@ void Preferences::Save() {
|
||||
if (this->mode == ModeReadOnly) {
|
||||
throw std::runtime_error("cannot save a ModeReadOnly Preference!");
|
||||
}
|
||||
|
||||
else if (this->mode != ModeTransient) {
|
||||
stringToFile(FILENAME(this->component), this->json.dump(2));
|
||||
}
|
||||
}
|
||||
|
||||
/* SDK IPreferences interface */
|
||||
|
@ -47,6 +47,7 @@ namespace musik { namespace core {
|
||||
class Preferences : public musik::core::sdk::IPreferences {
|
||||
public:
|
||||
enum Mode {
|
||||
ModeTransient,
|
||||
ModeReadOnly,
|
||||
ModeReadWrite,
|
||||
ModeAutoSave
|
||||
@ -55,6 +56,8 @@ namespace musik { namespace core {
|
||||
static void LoadPluginPreferences();
|
||||
static void SavePluginPreferences();
|
||||
|
||||
static musik::core::sdk::IPreferences* Unmanaged(const std::string& name);
|
||||
|
||||
static std::shared_ptr<Preferences>
|
||||
ForPlugin(const std::string& pluginName);
|
||||
|
||||
@ -64,15 +67,17 @@ namespace musik { namespace core {
|
||||
~Preferences();
|
||||
|
||||
/* IPreferences (for plugin use) */
|
||||
virtual bool GetBool(const char* key, bool defaultValue = false);
|
||||
virtual int GetInt(const char* key, int defaultValue = 0);
|
||||
virtual double GetDouble(const char* key, double defaultValue = 0.0f);
|
||||
virtual int GetString(const char* key, char* dst, size_t size, const char* defaultValue = "");
|
||||
virtual void Release() override;
|
||||
|
||||
virtual void SetBool(const char* key, bool value);
|
||||
virtual void SetInt(const char* key, int value);
|
||||
virtual void SetDouble(const char* key, double value);
|
||||
virtual void SetString(const char* key, const char* value);
|
||||
virtual bool GetBool(const char* key, bool defaultValue = false) override;
|
||||
virtual int GetInt(const char* key, int defaultValue = 0) override;
|
||||
virtual double GetDouble(const char* key, double defaultValue = 0.0f) override;
|
||||
virtual int GetString(const char* key, char* dst, size_t size, const char* defaultValue = "") override;
|
||||
|
||||
virtual void SetBool(const char* key, bool value) override;
|
||||
virtual void SetInt(const char* key, int value) override;
|
||||
virtual void SetDouble(const char* key, double value) override;
|
||||
virtual void SetString(const char* key, const char* value) override;
|
||||
|
||||
virtual void Save();
|
||||
|
||||
|
@ -105,23 +105,34 @@ class PluginAdapter : public ScrollAdapterBase {
|
||||
}
|
||||
|
||||
private:
|
||||
static std::string SortKey(const std::string& input) {
|
||||
std::string name = input;
|
||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
||||
return name;
|
||||
}
|
||||
|
||||
void Refresh() {
|
||||
plugins.clear();
|
||||
|
||||
PluginList& plugins = this->plugins;
|
||||
auto prefs = this->prefs;
|
||||
|
||||
typedef PluginFactory::NullDeleter<IPlugin> Deleter;
|
||||
using Deleter = PluginFactory::NullDeleter<IPlugin>;
|
||||
using Plugin = std::shared_ptr<IPlugin>;
|
||||
|
||||
PluginFactory::Instance().QueryInterface<IPlugin, Deleter>(
|
||||
"GetPlugin",
|
||||
[&plugins, prefs](std::shared_ptr<IPlugin> plugin, const std::string& fn) {
|
||||
[&plugins, prefs](Plugin plugin, const std::string& fn) {
|
||||
PluginInfoPtr info(new PluginInfo());
|
||||
info->name = plugin->Name();
|
||||
info->fn = boost::filesystem::path(fn).filename().string();
|
||||
info->enabled = prefs->GetBool(info->fn, true);
|
||||
plugins.push_back(info);
|
||||
});
|
||||
|
||||
std::sort(plugins.begin(), plugins.end(), [](PluginInfoPtr p1, PluginInfoPtr p2) -> bool {
|
||||
return SortKey(p1->name) < SortKey(p2->name);
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<Preferences> prefs;
|
||||
|
@ -33,8 +33,11 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "LameEncoder.h"
|
||||
#include "shared.h"
|
||||
#include <string>
|
||||
|
||||
using namespace musik::core::sdk;
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
static inline std::wstring utf8to16(const char* utf8) {
|
||||
@ -48,10 +51,9 @@ static inline std::wstring utf8to16(const char* utf8) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void LameEncoder::Release() {
|
||||
lame_close(lame);
|
||||
lame = nullptr;
|
||||
delete this;
|
||||
LameEncoder::LameEncoder() {
|
||||
this->lame = nullptr;
|
||||
this->prefs = env()->GetPreferences("LameEncoder");
|
||||
}
|
||||
|
||||
void LameEncoder::Initialize(size_t rate, size_t channels, size_t bitrate) {
|
||||
@ -66,6 +68,17 @@ void LameEncoder::Initialize(size_t rate, size_t channels, size_t bitrate) {
|
||||
lame_init_params(lame);
|
||||
}
|
||||
|
||||
void LameEncoder::Release() {
|
||||
lame_close(lame);
|
||||
lame = nullptr;
|
||||
this->prefs->Release();
|
||||
delete this;
|
||||
}
|
||||
|
||||
IPreferences* LameEncoder::GetPreferences() {
|
||||
return this->prefs;
|
||||
}
|
||||
|
||||
int LameEncoder::Encode(const IBuffer* pcm, char** data) {
|
||||
/* calculated according to lame.h */
|
||||
size_t channels = pcm->Channels();
|
||||
|
@ -40,14 +40,18 @@ class LameEncoder : public musik::core::sdk::IEncoder {
|
||||
using IBuffer = musik::core::sdk::IBuffer;
|
||||
|
||||
public:
|
||||
LameEncoder();
|
||||
|
||||
virtual void Release() override;
|
||||
virtual void Initialize(size_t rate, size_t channels, size_t bitrate) override;
|
||||
virtual int Encode(const IBuffer* pcm, char** data) override;
|
||||
virtual int Flush(char** data) override;
|
||||
virtual void Finalize(const char* uri) override;
|
||||
virtual musik::core::sdk::IPreferences* GetPreferences() override;
|
||||
|
||||
private:
|
||||
DataBuffer<unsigned char> encodedBytes;
|
||||
DataBuffer<float> downmix;
|
||||
musik::core::sdk::IPreferences* prefs;
|
||||
lame_t lame;
|
||||
};
|
@ -33,11 +33,14 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "OggEncoder.h"
|
||||
#include "shared.h"
|
||||
#include <random>
|
||||
|
||||
/* fre:ac/BoCA has an excellent example of vorbis encoder usage, a lot of code
|
||||
was adapted (stolen) from here: https://github.com/enzo1982/BoCA/blob/master/components/encoder/vorbis/vorbis.cpp */
|
||||
|
||||
using namespace musik::core::sdk;
|
||||
|
||||
void OggEncoder::Initialize(size_t rate, size_t channels, size_t bitrate) {
|
||||
ogg_stream_state os = { 0 };
|
||||
ogg_page og = { 0 };
|
||||
@ -48,6 +51,7 @@ void OggEncoder::Initialize(size_t rate, size_t channels, size_t bitrate) {
|
||||
vorbis_block vb = { 0 };
|
||||
this->bitrate = bitrate * 1000;
|
||||
this->headerWritten = false;
|
||||
this->prefs = env()->GetPreferences("OggEncoder");
|
||||
}
|
||||
|
||||
void OggEncoder::Release() {
|
||||
@ -56,9 +60,14 @@ void OggEncoder::Release() {
|
||||
vorbis_dsp_clear(&vd);
|
||||
vorbis_comment_clear(&vc);
|
||||
vorbis_info_clear(&vi);
|
||||
this->prefs->Release();
|
||||
delete this;
|
||||
}
|
||||
|
||||
IPreferences* OggEncoder::GetPreferences() {
|
||||
return this->prefs;
|
||||
}
|
||||
|
||||
int OggEncoder::Encode(const IBuffer* pcm, char** data) {
|
||||
encodedData.reset();
|
||||
|
||||
|
@ -48,11 +48,13 @@ class OggEncoder : public musik::core::sdk::IEncoder {
|
||||
virtual int Encode(const IBuffer* pcm, char** data) override;
|
||||
virtual int Flush(char** data) override;
|
||||
virtual void Finalize(const char* uri) override;
|
||||
virtual musik::core::sdk::IPreferences* GetPreferences() override;
|
||||
|
||||
private:
|
||||
int WritePackets(bool flush);
|
||||
|
||||
DataBuffer<char> encodedData;
|
||||
musik::core::sdk::IPreferences* prefs;
|
||||
long bitrate;
|
||||
bool headerWritten;
|
||||
ogg_stream_state os;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <core/sdk/IPlugin.h>
|
||||
#include <core/sdk/IEncoderFactory.h>
|
||||
|
||||
#include "shared.h"
|
||||
#include "LameEncoder.h"
|
||||
#include "OggEncoder.h"
|
||||
|
||||
@ -50,6 +51,8 @@
|
||||
|
||||
using namespace musik::core::sdk;
|
||||
|
||||
static IEnvironment* environment = nullptr;
|
||||
|
||||
static class Plugin : public IPlugin {
|
||||
public:
|
||||
Plugin() {
|
||||
@ -120,3 +123,11 @@ extern "C" DLL_EXPORT IPlugin* GetPlugin() {
|
||||
extern "C" DLL_EXPORT IEncoderFactory* GetEncoderFactory() {
|
||||
return &encoderFactory;
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT void SetEnvironment(musik::core::sdk::IEnvironment* env) {
|
||||
environment = env;
|
||||
}
|
||||
|
||||
IEnvironment* env() {
|
||||
return environment;
|
||||
}
|
39
src/plugins/stockencoders/shared.h
Normal file
39
src/plugins/stockencoders/shared.h
Normal file
@ -0,0 +1,39 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2017 musikcube team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/sdk/IEnvironment.h>
|
||||
|
||||
extern musik::core::sdk::IEnvironment* env();
|
@ -152,6 +152,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="LameEncoder.h" />
|
||||
<ClInclude Include="OggEncoder.h" />
|
||||
<ClInclude Include="shared.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -24,5 +24,8 @@
|
||||
<ClInclude Include="OggEncoder.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shared.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user