mirror of
https://github.com/clangen/musikcube.git
synced 2024-10-01 20:42:13 +00:00
Added a new IDebug
interface to the SDK -- plugins can opt-in to get an instance to one of these and write debug information to the standard location, just like the rest of the app.
This commit is contained in:
parent
1b4b9127c4
commit
cc134775ef
@ -10,6 +10,7 @@ musikcube:
|
||||
* added the ability to customize the key used to quit the app. it is currently
|
||||
not exposed in the ui, but it can be changed by editing
|
||||
`~/.musikcube/settings.json` and updating the `AppQuitKey`.
|
||||
* scrapped and re-implemented the debug log viewer, accessible via `ctrl+~`
|
||||
* added feodra 29 support (dvdmuckle)
|
||||
* fixed configuration script bugs that were causing breakage in FreeBSD
|
||||
* migrated to non-bundled `taglib` for macOS and most Linux distributions
|
||||
@ -19,6 +20,10 @@ musikcube:
|
||||
musikdroid:
|
||||
* updated to compile against the latest tooling
|
||||
|
||||
sdk:
|
||||
* added a new `IDebug` interface plugins can request via `SetDebug` to write
|
||||
log information to the standard location, just like the rest of the app.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
0.51.0
|
||||
|
@ -99,11 +99,8 @@ void GaplessTransport::PrepareNextTrack(const std::string& uri, Gain gain) {
|
||||
}
|
||||
|
||||
void GaplessTransport::Start(const std::string& uri, Gain gain, StartMode mode) {
|
||||
musik::debug::info(TAG, "we were asked to start the track at " + uri);
|
||||
|
||||
musik::debug::info(TAG, "starting track at " + uri);
|
||||
Player* newPlayer = Player::Create(uri, this->output, Player::NoDrain, this, gain);
|
||||
musik::debug::info(TAG, "Player created successfully");
|
||||
|
||||
this->StartWithPlayer(newPlayer, mode);
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ namespace musik { namespace core { namespace audio {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
musik::debug::info(TAG, "about ready to play: " + uri);
|
||||
musik::debug::info(TAG, "found a decoder for " + uri);
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
@ -92,7 +92,6 @@ bool LocalFileStream::Open(const char *filename, unsigned int options) {
|
||||
#endif
|
||||
|
||||
if (this->file.load()) {
|
||||
debug::info(TAG, "opened successfully");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <core/support/Common.h>
|
||||
#include <core/support/Preferences.h>
|
||||
|
||||
#include <core/debug.h>
|
||||
#include <core/io/DataStreamFactory.h>
|
||||
#include <core/audio/Buffer.h>
|
||||
#include <core/audio/Streams.h>
|
||||
@ -49,6 +50,7 @@
|
||||
#include <core/runtime/Message.h>
|
||||
#include <core/support/Messages.h>
|
||||
|
||||
#include <core/sdk/IDebug.h>
|
||||
#include <core/sdk/IIndexerNotifier.h>
|
||||
#include <core/sdk/IEnvironment.h>
|
||||
|
||||
@ -60,6 +62,7 @@ using namespace musik::core::runtime;
|
||||
using namespace musik::core::sdk;
|
||||
|
||||
typedef void(*SetEnvironment)(IEnvironment*);
|
||||
typedef void(*SetDebug)(IDebug*);
|
||||
typedef void(*SetSimpleDataProvider)(ISimpleDataProvider*);
|
||||
typedef void(*SetIndexerNotifier)(IIndexerNotifier*);
|
||||
|
||||
@ -79,7 +82,26 @@ static void saveEnvironment() {
|
||||
}
|
||||
}
|
||||
|
||||
static class Environment : public IEnvironment {
|
||||
static class Debug: public IDebug {
|
||||
public:
|
||||
virtual void Verbose(const char* tag, const char* message) override {
|
||||
musik::debug::verbose(tag, message);
|
||||
}
|
||||
|
||||
virtual void Info(const char* tag, const char* message) override {
|
||||
musik::debug::info(tag, message);
|
||||
}
|
||||
|
||||
virtual void Warning(const char* tag, const char* message) override {
|
||||
musik::debug::warning(tag, message);
|
||||
}
|
||||
|
||||
virtual void Error(const char* tag, const char* message) override {
|
||||
musik::debug::error(tag, message);
|
||||
}
|
||||
} debugger;
|
||||
|
||||
static class Environment: public IEnvironment {
|
||||
public:
|
||||
virtual size_t GetPath(PathType type, char* dst, int size) override {
|
||||
std::string path;
|
||||
@ -110,6 +132,10 @@ static class Environment : public IEnvironment {
|
||||
return streams::GetEncoderForType(type);
|
||||
}
|
||||
|
||||
virtual IDebug* GetDebug() override {
|
||||
return &debugger;
|
||||
}
|
||||
|
||||
virtual IPreferences* GetPreferences(const char* name) override {
|
||||
return Preferences::Unmanaged(name ? name : std::string());
|
||||
}
|
||||
@ -266,6 +292,13 @@ namespace musik { namespace core { namespace plugin {
|
||||
[](musik::core::sdk::IPlugin* plugin, SetEnvironment func) {
|
||||
func(&environment);
|
||||
});
|
||||
|
||||
/* debug */
|
||||
PluginFactory::Instance().QueryFunction<SetDebug>(
|
||||
"SetDebug",
|
||||
[](musik::core::sdk::IPlugin* plugin, SetDebug func) {
|
||||
func(&debugger);
|
||||
});
|
||||
}
|
||||
|
||||
void UninstallDependencies() {
|
||||
@ -299,6 +332,13 @@ namespace musik { namespace core { namespace plugin {
|
||||
[](musik::core::sdk::IPlugin* plugin, SetEnvironment func) {
|
||||
func(nullptr);
|
||||
});
|
||||
|
||||
/* debug */
|
||||
PluginFactory::Instance().QueryFunction<SetDebug>(
|
||||
"SetDebug",
|
||||
[](musik::core::sdk::IPlugin* plugin, SetDebug func) {
|
||||
func(nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
} } }
|
||||
|
47
src/core/sdk/IDebug.h
Normal file
47
src/core/sdk/IDebug.h
Normal file
@ -0,0 +1,47 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
|
||||
namespace musik { namespace core { namespace sdk {
|
||||
|
||||
class IDebug {
|
||||
public:
|
||||
virtual void Verbose(const char* tag, const char* message) = 0;
|
||||
virtual void Info(const char* tag, const char* message) = 0;
|
||||
virtual void Warning(const char* tag, const char* message) = 0;
|
||||
virtual void Error(const char* tag, const char* message) = 0;
|
||||
};
|
||||
|
||||
} } }
|
@ -41,6 +41,7 @@
|
||||
#include "IPreferences.h"
|
||||
#include "IOutput.h"
|
||||
#include "ITrackList.h"
|
||||
#include "IDebug.h"
|
||||
|
||||
namespace musik { namespace core { namespace sdk {
|
||||
|
||||
@ -52,6 +53,7 @@ namespace musik { namespace core { namespace sdk {
|
||||
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;
|
||||
virtual IDebug* GetDebug() = 0;
|
||||
virtual size_t GetOutputCount() = 0;
|
||||
virtual IOutput* GetOutputAtIndex(size_t index) = 0;
|
||||
virtual IOutput* GetOutputWithName(const char* name) = 0;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <cursespp/ToastOverlay.h>
|
||||
#include <app/util/Hotkeys.h>
|
||||
#include <app/util/Messages.h>
|
||||
#include <app/version.h>
|
||||
|
||||
using namespace musik::cube;
|
||||
using namespace musik::core;
|
||||
@ -55,6 +56,18 @@ void ConsoleLayout::OnItemActivated(cursespp::ListWindow* window, size_t index)
|
||||
ToastOverlay::Show(this->logger->Adapter()->StringAt(index), -1);
|
||||
}
|
||||
|
||||
bool ConsoleLayout::KeyPress(const std::string& kn) {
|
||||
if (kn == "^_") { /* ctrl+/ */
|
||||
ToastOverlay::Show(u8fmt(_TSTR("console_version"), VERSION), -1);
|
||||
return true;
|
||||
}
|
||||
else if (kn == "x") {
|
||||
this->adapter->Clear();
|
||||
return true;
|
||||
}
|
||||
return LayoutBase::KeyPress(kn);
|
||||
}
|
||||
|
||||
void ConsoleLayout::SetShortcutsWindow(ShortcutsWindow* shortcuts) {
|
||||
if (shortcuts) {
|
||||
shortcuts->AddShortcut(Hotkeys::Get(Hotkeys::NavigateConsole), _TSTR("shortcuts_console"));
|
||||
|
@ -17,6 +17,7 @@ namespace musik { namespace cube {
|
||||
|
||||
virtual void OnLayout() override;
|
||||
virtual void SetShortcutsWindow(cursespp::ShortcutsWindow* w) override;
|
||||
virtual bool KeyPress(const std::string& kn) override;
|
||||
|
||||
protected:
|
||||
void OnVisibilityChanged(bool visible) override;
|
||||
|
@ -36,6 +36,7 @@
|
||||
"browse_no_subdirectories_toast": "there are no more sub-directories.\n\npress '%s' to play the selection.",
|
||||
|
||||
"console_list_title": "debug logs",
|
||||
"console_version": "musikcube version %s",
|
||||
|
||||
"hotkeys_title": "key bindings",
|
||||
"hotkeys_reset_defaults": "reset all",
|
||||
|
@ -33,13 +33,27 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FfmpegDecoder.h"
|
||||
#include <core/sdk/IDebug.h>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#endif
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
#define PROBE_SIZE 32768
|
||||
|
||||
using namespace musik::core::sdk;
|
||||
|
||||
static const char* TAG = "ffmpegdecoder";
|
||||
static IDebug* debug = nullptr;
|
||||
|
||||
extern "C" DLLEXPORT void SetDebug(IDebug* debug) {
|
||||
::debug = debug;
|
||||
}
|
||||
|
||||
static int readCallback(void* opaque, uint8_t* buffer, int bufferSize) {
|
||||
FfmpegDecoder* decoder = static_cast<FfmpegDecoder*>(opaque);
|
||||
if (decoder && decoder->Stream()) {
|
||||
@ -182,6 +196,9 @@ bool FfmpegDecoder::GetBuffer(IBuffer *buffer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
::debug->Warning(TAG, "finished decoding.");
|
||||
this->exhausted = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -214,6 +231,8 @@ void FfmpegDecoder::Reset() {
|
||||
|
||||
bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
|
||||
if (stream->Seekable() && this->ioContext == nullptr) {
|
||||
::debug->Info(TAG, "parsing data stream...");
|
||||
|
||||
this->stream = stream;
|
||||
|
||||
this->ioContext = avio_alloc_context(
|
||||
@ -254,6 +273,7 @@ bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
|
||||
}
|
||||
|
||||
if (this->streamId != -1) {
|
||||
::debug->Info(TAG, "found audio!");
|
||||
this->codecContext = this->formatContext->streams[this->streamId]->codec;
|
||||
if (codecContext) {
|
||||
this->codecContext->request_sample_fmt = AV_SAMPLE_FMT_FLT;
|
||||
@ -262,8 +282,10 @@ bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
|
||||
if (avcodec_open2(codecContext, codec, nullptr) < 0) {
|
||||
goto reset_and_fail;
|
||||
}
|
||||
::debug->Info(TAG, "resolved a codec!");
|
||||
}
|
||||
else {
|
||||
::debug->Error(TAG, "couldn't find a codec.");
|
||||
goto reset_and_fail;
|
||||
}
|
||||
}
|
||||
@ -274,16 +296,20 @@ bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
|
||||
this->duration = (double) this->formatContext->duration / (double) AV_TIME_BASE;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
::debug->Error(TAG, "audio stream not found in input data.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset_and_fail:
|
||||
::debug->Error(TAG, "failed to find compatible audio stream");
|
||||
this->Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FfmpegDecoder::Exhausted() {
|
||||
return false;
|
||||
return this->exhausted;
|
||||
}
|
@ -80,4 +80,5 @@ class FfmpegDecoder: public musik::core::sdk::IDecoder {
|
||||
size_t rate, channels;
|
||||
int streamId;
|
||||
double duration;
|
||||
bool exhausted{false};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user