mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-11 18:40:28 +00:00
The beginnings of a logging infrastructure and a few more bug fixes and
cleanups.
This commit is contained in:
parent
e7fec08771
commit
1eee0ed459
@ -75,7 +75,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../;../../3rdparty/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../;../../3rdparty/include;../../../../boost_1_60_0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
|
@ -105,6 +105,7 @@
|
||||
<ClCompile Include="library\track\LibraryTrack.cpp" />
|
||||
<ClCompile Include="library\track\Track.cpp" />
|
||||
<ClCompile Include="library\track\TrackFactory.cpp" />
|
||||
<ClCompile Include="log\debug.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
@ -148,6 +149,7 @@
|
||||
<ClInclude Include="library\track\LibraryTrack.h" />
|
||||
<ClInclude Include="library\track\Track.h" />
|
||||
<ClInclude Include="library\track\TrackFactory.h" />
|
||||
<ClInclude Include="log\debug.h" />
|
||||
<ClInclude Include="pch.hpp" />
|
||||
<ClInclude Include="config.h" />
|
||||
<ClInclude Include="playback\NonLibraryTrackHelper.h" />
|
||||
|
@ -38,6 +38,9 @@
|
||||
<Filter Include="src\library\metadata">
|
||||
<UniqueIdentifier>{9f9ee41d-111b-4dab-8663-946253eeb46f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\log">
|
||||
<UniqueIdentifier>{66b1a48d-9dee-4b10-86cd-e6893c283440}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
@ -154,6 +157,9 @@
|
||||
<ClCompile Include="library\metadata\MetadataValue.cpp">
|
||||
<Filter>src\library\metadata</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="log\debug.cpp">
|
||||
<Filter>src\log</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.hpp">
|
||||
@ -315,5 +321,8 @@
|
||||
<ClInclude Include="sdk\IPlugin.h">
|
||||
<Filter>src\sdk</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="log\debug.h">
|
||||
<Filter>src\log</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include "pch.hpp"
|
||||
|
||||
#include <core/log/debug.h>
|
||||
#include <core/io/LocalFileStream.h>
|
||||
#include <core/config.h>
|
||||
#include <core/support/Common.h>
|
||||
@ -69,11 +70,11 @@ bool LocalFileStream::Open(const char *filename, unsigned int options) {
|
||||
boost::filesystem::path file(filename);
|
||||
|
||||
if (!boost::filesystem::exists(file)) {
|
||||
std::cerr << "File not found" << std::endl;
|
||||
debug::log("LocalFileStream", "file not found");
|
||||
}
|
||||
|
||||
if (!boost::filesystem::is_regular(file)) {
|
||||
std::cerr << "File not a regular file" << std::endl;
|
||||
debug::log("LocalFileStream", "not a regular file");
|
||||
}
|
||||
|
||||
this->filesize = (long)boost::filesystem::file_size(file);
|
||||
@ -113,7 +114,7 @@ PositionType LocalFileStream::Read(void* buffer,PositionType readBytes) {
|
||||
}
|
||||
catch (std::ios_base::failure){
|
||||
if(!this->fileStream->eof()) {
|
||||
std::cerr << "Error reading from file" << std::endl;
|
||||
debug::log("LocalFileStream", "file read error");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include "pch.hpp"
|
||||
|
||||
#include <core/log/debug.h>
|
||||
#include <core/library/Indexer.h>
|
||||
|
||||
#include <core/config.h>
|
||||
@ -87,17 +88,17 @@ std::string Indexer::GetStatus() {
|
||||
boost::mutex::scoped_lock lock(this->progressMutex);
|
||||
|
||||
switch (status) {
|
||||
case 1: return boost::str(boost::format("Counting files: %1%") % this->nofFiles);
|
||||
case 2: return boost::str(boost::format("Indexing: %.2f") % (this->overallProgress * 100)) + "%";
|
||||
case 3: return boost::str(boost::format("Removing old files: %.2f") % (this->overallProgress * 100)) + "%";
|
||||
case 4: return "Cleaning up.";
|
||||
case 5: return "Optimizing.";
|
||||
case 6: return boost::str(boost::format("Analyzing: %.2f%% (current %.1f%%)")
|
||||
case 1: return boost::str(boost::format("counting... %1%") % this->nofFiles);
|
||||
case 2: return boost::str(boost::format("indexing... %.2f") % (this->overallProgress * 100)) + "%";
|
||||
case 3: return boost::str(boost::format("removing... %.2f") % (this->overallProgress * 100)) + "%";
|
||||
case 4: return "cleaning...";
|
||||
case 5: return "optimizing...";
|
||||
case 6: return boost::str(boost::format("running analyzers...: %.2f%% (current %.1f%%)")
|
||||
% (100.0 * this->overallProgress / (double) this->nofFiles)
|
||||
% (this->currentProgress * 100.0));
|
||||
}
|
||||
|
||||
return "unknown indexer status";
|
||||
return "doing something... (unknown)";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
@ -402,7 +403,7 @@ void Indexer::SyncDirectory(
|
||||
for( ; file != end && !this->Exited() && !this->Restarted();++file) {
|
||||
if (is_directory(file->status())) {
|
||||
/* recursion here */
|
||||
std::cout << this->GetStatus() << "\n";
|
||||
musik::debug::log("indexer", this->GetStatus());
|
||||
this->SyncDirectory(file->path().string(), dirId,pathId,syncPath);
|
||||
}
|
||||
else {
|
||||
|
157
src/core/log/debug.cpp
Executable file
157
src/core/log/debug.cpp
Executable file
@ -0,0 +1,157 @@
|
||||
#include "pch.hpp"
|
||||
|
||||
#include <core/log/debug.h>
|
||||
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
using namespace musik;
|
||||
|
||||
sigslot::signal3<debug::log_level, std::string, std::string> debug::string_logged;
|
||||
|
||||
namespace musik {
|
||||
/*
|
||||
* Basically ripped and simplified from message_queue. Log statements get
|
||||
* enqueued and processed on a background thread.
|
||||
*/
|
||||
class log_queue {
|
||||
public:
|
||||
struct log_entry {
|
||||
log_entry(debug::log_level l, const std::string& t, const std::string& m) {
|
||||
level_ = l;
|
||||
tag_ = t;
|
||||
message_ = m;
|
||||
}
|
||||
|
||||
debug::log_level level_;
|
||||
std::string tag_;
|
||||
std::string message_;
|
||||
};
|
||||
|
||||
class stopped_exception {
|
||||
};
|
||||
|
||||
private:
|
||||
std::queue<log_entry*> queue_;
|
||||
boost::condition_variable wait_for_next_item_condition_;
|
||||
boost::mutex queue_mutex_;
|
||||
volatile bool active_;
|
||||
|
||||
public:
|
||||
log_queue() {
|
||||
active_ = true;
|
||||
}
|
||||
|
||||
log_entry* pop_top() {
|
||||
boost::mutex::scoped_lock lock(queue_mutex_);
|
||||
while ((queue_.size() == 0) && (active_ == true)) {
|
||||
wait_for_next_item_condition_.wait(lock);
|
||||
}
|
||||
|
||||
if (!active_) {
|
||||
throw stopped_exception();
|
||||
}
|
||||
|
||||
log_entry* top = queue_.front();
|
||||
queue_.pop();
|
||||
return top;
|
||||
}
|
||||
|
||||
bool push(log_entry* f) {
|
||||
boost::mutex::scoped_lock lock(queue_mutex_);
|
||||
|
||||
if (active_) {
|
||||
bool was_empty = (queue_.size() == 0);
|
||||
queue_.push(f);
|
||||
|
||||
if (was_empty) {
|
||||
wait_for_next_item_condition_.notify_one();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void stop() {
|
||||
boost::mutex::scoped_lock lock(queue_mutex_);
|
||||
active_ = false;
|
||||
|
||||
while (queue_.size() > 0) {
|
||||
log_entry* top = queue_.front();
|
||||
queue_.pop();
|
||||
delete top;
|
||||
}
|
||||
|
||||
wait_for_next_item_condition_.notify_all();
|
||||
}
|
||||
};
|
||||
} // namespace autom8
|
||||
|
||||
static boost::thread* thread_ = NULL;
|
||||
static log_queue* queue_ = NULL;
|
||||
static boost::recursive_mutex system_mutex_;
|
||||
static volatile bool cancel_ = true;
|
||||
|
||||
static void thread_proc() {
|
||||
std::string s;
|
||||
try {
|
||||
while (!cancel_) {
|
||||
log_queue::log_entry* entry = queue_->pop_top();
|
||||
debug::string_logged(entry->level_, entry->tag_, entry->message_);
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
catch (log_queue::stopped_exception&) {
|
||||
}
|
||||
}
|
||||
|
||||
void debug::init() {
|
||||
boost::recursive_mutex::scoped_lock lock(system_mutex_);
|
||||
|
||||
if (queue_ || thread_) {
|
||||
return;
|
||||
}
|
||||
|
||||
deinit();
|
||||
|
||||
cancel_ = false;
|
||||
queue_ = new log_queue();
|
||||
thread_ = new boost::thread(boost::bind(&thread_proc));
|
||||
}
|
||||
|
||||
void debug::deinit() {
|
||||
boost::recursive_mutex::scoped_lock lock(system_mutex_);
|
||||
|
||||
cancel_ = true;
|
||||
|
||||
if (thread_ && queue_) {
|
||||
/* ordering is important here... stop the queue, then
|
||||
join the thread. stop will trigger a stopped_exception the
|
||||
thread may be blocking on, waiting for the next message */
|
||||
queue_->stop();
|
||||
thread_->join();
|
||||
|
||||
/* don't delete anything until the join has completed */
|
||||
delete thread_;
|
||||
thread_ = NULL;
|
||||
delete queue_;
|
||||
queue_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void debug::log(const std::string& tag, const std::string& string) {
|
||||
log(debug::info, tag, string);
|
||||
}
|
||||
|
||||
void debug::log(log_level level, const std::string& tag, const std::string& string) {
|
||||
boost::recursive_mutex::scoped_lock lock(system_mutex_);
|
||||
|
||||
if (queue_) {
|
||||
queue_->push(new log_queue::log_entry(level, tag, string));
|
||||
}
|
||||
}
|
||||
|
24
src/core/log/debug.h
Executable file
24
src/core/log/debug.h
Executable file
@ -0,0 +1,24 @@
|
||||
#ifndef __C_AUTOM8_DEBUG_HPP__
|
||||
#define __C_AUTOM8_DEBUG_HPP__
|
||||
|
||||
#include <sigslot/sigslot.h>
|
||||
#include <string>
|
||||
|
||||
namespace musik {
|
||||
class debug {
|
||||
public:
|
||||
enum log_level {
|
||||
info = 0,
|
||||
warning,
|
||||
error
|
||||
};
|
||||
|
||||
static void init();
|
||||
static void deinit();
|
||||
static sigslot::signal3<log_level, std::string, std::string> string_logged;
|
||||
static void log(log_level level, const std::string& tag, const std::string& string);
|
||||
static void log(const std::string& tag, const std::string& string);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "pch.hpp"
|
||||
|
||||
#include <core/log/debug.h>
|
||||
#include <core/playback/Transport.h>
|
||||
|
||||
using namespace musik::core::audio;
|
||||
@ -61,45 +62,39 @@ void Transport::PrepareNextTrack(std::string trackUrl){
|
||||
}
|
||||
|
||||
void Transport::Start(std::string url){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Transport::Start called" << std::endl;
|
||||
#endif
|
||||
musik::debug::log("transport", "start");
|
||||
|
||||
// Check if this is already Prepared
|
||||
PlayerPtr player = this->nextPlayer;
|
||||
PlayerPtr player = this->nextPlayer;
|
||||
this->nextPlayer.reset();
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Transport: nextPlayer reset" << std::endl;
|
||||
#endif
|
||||
|
||||
musik::debug::log("transport", "next player reset");
|
||||
|
||||
// If the nextPlayer wasn't the same as the one started, lets create a new one
|
||||
if(!player || player->url!=url){
|
||||
// Or create a new player
|
||||
Player::OutputPtr output;
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Transport: new output created for player" << std::endl;
|
||||
#endif
|
||||
musik::debug::log("transport", "created output device");
|
||||
|
||||
player = Player::Create(url, &output);
|
||||
player->SetVolume(this->volume);
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Transport: new player created" << std::endl;
|
||||
#endif
|
||||
|
||||
musik::debug::log("transport", "created player");
|
||||
}
|
||||
|
||||
// Add to the players
|
||||
this->players.push_front(player);
|
||||
this->currentPlayer = player;
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Transport: player added to player list" << std::endl;
|
||||
#endif
|
||||
|
||||
musik::debug::log("transport", "player added to player list");
|
||||
|
||||
// Lets connect to the signals of the currentPlayer
|
||||
this->currentPlayer->PlaybackStarted.connect(this,&Transport::OnPlaybackStarted);
|
||||
this->currentPlayer->PlaybackAlmostEnded.connect(this,&Transport::OnPlaybackAlmostEnded);
|
||||
this->currentPlayer->PlaybackEnded.connect(this,&Transport::OnPlaybackEnded);
|
||||
this->currentPlayer->PlaybackError.connect(this, &Transport::OnPlaybackError);
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Transport: player-Play() about to be called" << std::endl;
|
||||
#endif
|
||||
|
||||
musik::debug::log("transport", "play()");
|
||||
|
||||
// Start playing
|
||||
player->Play();
|
||||
}
|
||||
|
@ -36,171 +36,177 @@
|
||||
#include "ConsoleUI.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <core/log/debug.h>
|
||||
#include <core/sdk/IPlugin.h>
|
||||
#include <core/plugin/PluginFactory.h>
|
||||
|
||||
#include <core/library/track/TrackFactory.h>
|
||||
#include <core/library/LibraryFactory.h>
|
||||
#include <core/library/Indexer.h>
|
||||
|
||||
template <class T>
|
||||
bool tostr(T& t, const std::string& s) {
|
||||
std::istringstream iss(s);
|
||||
return !(iss >> t).fail();
|
||||
}
|
||||
|
||||
using namespace musik::square;
|
||||
|
||||
using std::cout;
|
||||
using std::cin;
|
||||
using musik::core::Indexer;
|
||||
using musik::core::IndexerPtr;
|
||||
using musik::core::LibraryFactory;
|
||||
using musik::core::LibraryPtr;
|
||||
using musik::core::TrackFactory;
|
||||
using musik::core::TrackPtr;
|
||||
|
||||
static boost::mutex outputMutex;
|
||||
|
||||
typedef boost::mutex::scoped_lock Lock;
|
||||
static Lock lockOutput() {
|
||||
return Lock(outputMutex);
|
||||
}
|
||||
|
||||
ConsoleUI::ConsoleUI()
|
||||
: shouldQuit(false)
|
||||
, audioEventHandler(this)
|
||||
, paused(false)
|
||||
{
|
||||
// this->transport.EventPlaybackStartedOk.connect(&audioEventHandler, &DummyAudioEventHandler::OnPlaybackStartedOk);
|
||||
// this->transport.EventPlaybackStartedFail.connect(&audioEventHandler, &DummyAudioEventHandler::OnPlaybackStartedFail);
|
||||
, paused(false) {
|
||||
|
||||
// this->transport.EventPlaybackStoppedOk.connect(&audioEventHandler, &DummyAudioEventHandler::OnPlaybackStoppedOk);
|
||||
// this->transport.EventPlaybackStoppedFail.connect(&audioEventHandler, &DummyAudioEventHandler::OnPlaybackStoppedFail);
|
||||
musik::debug::string_logged.connect(this, &ConsoleUI::OnDebug);
|
||||
|
||||
// this->transport.EventVolumeChangedOk.connect(&audioEventHandler, &DummyAudioEventHandler::OnVolumeChangedOk);
|
||||
// this->transport.EventVolumeChangedFail.connect(&audioEventHandler, &DummyAudioEventHandler::OnVolumeChangedFail);
|
||||
// this->transport.EventPlaybackStopped.connect(&audioEventHandler, &TransportEvents::OnPlaybackStopped);
|
||||
// this->transport.EventVolumeChanged.connect(&audioEventHandler, &TransportEvents::OnVolumeChanged);
|
||||
// this->transport.EventMixpointReached.connect(&audioEventHandler, &TransportEvents::OnMixpointReached);
|
||||
this->transport.PlaybackStarted.connect(&this->audioEventHandler, &TransportEvents::OnPlaybackStartedOk);
|
||||
this->transport.PlaybackAlmostDone.connect(&this->audioEventHandler, &TransportEvents::OnPlaybackAlmostEnded);
|
||||
this->transport.PlaybackEnded.connect(&this->audioEventHandler, &TransportEvents::OnPlaybackStoppedOk);
|
||||
this->transport.PlaybackError.connect(&this->audioEventHandler, &TransportEvents::OnPlaybackStoppedFail);
|
||||
this->transport.PlaybackPause.connect(&this->audioEventHandler, &TransportEvents::OnPlaybackPaused);
|
||||
this->transport.PlaybackResume.connect(&this->audioEventHandler, &TransportEvents::OnPlaybackResumed);
|
||||
|
||||
// this->transport.EventMixpointReached.connect(&audioEventHandler, &DummyAudioEventHandler::OnMixpointReached);
|
||||
|
||||
this->transport.PlaybackStarted.connect(&this->audioEventHandler, &DummyAudioEventHandler::OnPlaybackStartedOk);
|
||||
this->transport.PlaybackAlmostDone.connect(&this->audioEventHandler, &DummyAudioEventHandler::OnPlaybackAlmostEnded);
|
||||
this->transport.PlaybackEnded.connect(&this->audioEventHandler, &DummyAudioEventHandler::OnPlaybackStoppedOk);
|
||||
this->transport.PlaybackError.connect(&this->audioEventHandler, &DummyAudioEventHandler::OnPlaybackStoppedFail);
|
||||
}
|
||||
|
||||
void ConsoleUI::OnDebug(musik::debug::log_level level, std::string tag, std::string message) {
|
||||
std::cout << " [" << tag << "] " << message << "\n";
|
||||
}
|
||||
|
||||
ConsoleUI::~ConsoleUI() {
|
||||
}
|
||||
|
||||
void ConsoleUI::Print(std::string s)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
|
||||
cout << "\n*******************************\n\n";
|
||||
cout << s;
|
||||
cout << "\n*******************************\n" << std::endl;
|
||||
}
|
||||
|
||||
void ConsoleUI::Run()
|
||||
{
|
||||
std::string command;
|
||||
void ConsoleUI::Run() {
|
||||
std::string cmd;
|
||||
|
||||
transport.SetVolume(0.1);
|
||||
|
||||
using musik::core::Indexer;
|
||||
using musik::core::IndexerPtr;
|
||||
using musik::core::LibraryFactory;
|
||||
using musik::core::LibraryPtr;
|
||||
using musik::core::TrackFactory;
|
||||
using musik::core::TrackPtr;
|
||||
|
||||
LibraryPtr library = LibraryFactory::Libraries().at(0); /* there's always at least 1... */
|
||||
library->Indexer()->AddPath("E:/music/");
|
||||
library->Indexer()->RestartSync();
|
||||
|
||||
this->Help();
|
||||
|
||||
while (!this->shouldQuit) {
|
||||
this->PrintCommands();
|
||||
cout << "Enter command: ";
|
||||
std::getline(cin, command); // Need getline to handle spaces!
|
||||
this->ProcessCommand(command);
|
||||
cout << "> ";
|
||||
std::getline(cin, cmd);
|
||||
this->Process(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleUI::PrintCommands()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
void ConsoleUI::Help() {
|
||||
Lock lock = lockOutput();
|
||||
|
||||
cout << "Commands:\n";
|
||||
cout << "\tp [file]: play file (enter full path)\n";
|
||||
cout << "\ts: stop playing\n";
|
||||
cout << "\tl: list currently playing\n";
|
||||
cout << "\tlp: list loaded plugins\n";
|
||||
cout << "\tv <p>: set volume to p%\n";
|
||||
cout << "\tq: quit";
|
||||
cout << std::endl;
|
||||
cout << "help:\n";
|
||||
cout << " pl [file]: play file at path\n";
|
||||
cout << " pa: toggle pause/resume";
|
||||
cout << " st: stop playing\n";
|
||||
cout << " ls: list currently playing\n";
|
||||
cout << " lp: list loaded plugins\n";
|
||||
cout << " v: <0.0-1.0>: set volume to p%\n";
|
||||
cout << " sk <seconds>: seek to <seconds> into track\n";
|
||||
cout << " rescan: rescan/index music directories\n";
|
||||
cout << "\n q: quit\n\n";
|
||||
}
|
||||
|
||||
void ConsoleUI::ProcessCommand(std::string commandString)
|
||||
void ConsoleUI::Process(const std::string& cmd)
|
||||
{
|
||||
Args args;
|
||||
|
||||
boost::algorithm::split(args, commandString, boost::is_any_of(" "));
|
||||
boost::algorithm::split(args, cmd, boost::is_any_of(" "));
|
||||
|
||||
std::string command = args.size() > 0 ? args[0] : "";
|
||||
args.erase(args.begin());
|
||||
|
||||
if (command == "p")
|
||||
{
|
||||
if (command == "rmdir") {
|
||||
|
||||
}
|
||||
else if (command == "addir") {
|
||||
|
||||
}
|
||||
else if (command == "dirs") {
|
||||
|
||||
}
|
||||
else if (command == "rescan" || command == "scan" || command == "index") {
|
||||
LibraryPtr library = LibraryFactory::Libraries().at(0); /* there's always at least 1... */
|
||||
library->Indexer()->RestartSync();
|
||||
}
|
||||
else if (command == "h" || command == "help") {
|
||||
this->Help();
|
||||
}
|
||||
else if (command == "p" || command == "pl") {
|
||||
this->PlayFile(args);
|
||||
}
|
||||
else if (command == "pa")
|
||||
{
|
||||
else if (command == "pa") {
|
||||
this->Pause();
|
||||
}
|
||||
else if (command == "s")
|
||||
{
|
||||
else if (command == "s") {
|
||||
this->Stop(args);
|
||||
}
|
||||
else if (command == "seek")
|
||||
{
|
||||
this->SetPosition(args);
|
||||
else if (command == "sk" || command == "seek") {
|
||||
this->SetPosition(args);
|
||||
}
|
||||
else if (command == "l")
|
||||
{
|
||||
else if (command == "np" || command == "pl") {
|
||||
this->ListPlaying();
|
||||
}
|
||||
else if (command == "lp")
|
||||
{
|
||||
else if (command == "plugins") {
|
||||
this->ListPlugins();
|
||||
}
|
||||
else if (command == "v")
|
||||
{
|
||||
else if (command == "v" || command == "volume") {
|
||||
this->SetVolume(args);
|
||||
}
|
||||
else if (command == "q")
|
||||
{
|
||||
else if (command == "q" || command == "quit" || command == "exit") {
|
||||
this->Quit();
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unknown command\n";
|
||||
else {
|
||||
cout << "\n\nunknown command ('h' for help)\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleUI::PlayFile(Args args)
|
||||
{
|
||||
void ConsoleUI::PlayFile(Args args) {
|
||||
std::string filename;
|
||||
if (args.size() > 0)
|
||||
{
|
||||
if (args.size() > 0) {
|
||||
filename = args[0];
|
||||
}
|
||||
|
||||
int repeat = 1;
|
||||
if (args.size() > 1)
|
||||
{
|
||||
convertString<int>(repeat, args[1]);
|
||||
if (args.size() > 1) {
|
||||
tostr<int>(repeat, args[1]);
|
||||
}
|
||||
|
||||
unsigned int delay = 0;
|
||||
if (args.size() > 2)
|
||||
{
|
||||
if (!convertString<unsigned int>(delay, args[2]))
|
||||
{
|
||||
if (args.size() > 2) {
|
||||
if (!tostr<unsigned int>(delay, args[2])) {
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < repeat; ++i)
|
||||
{
|
||||
for (int i = 0; i < repeat; ++i) {
|
||||
transport.Start(filename.c_str()); //TODO: fix to use TrackPtr
|
||||
if (delay)
|
||||
{
|
||||
if (delay) {
|
||||
#ifdef WIN32
|
||||
Sleep(delay);
|
||||
Sleep(delay);
|
||||
#else
|
||||
sleep(delay);
|
||||
#endif
|
||||
@ -208,111 +214,91 @@ void ConsoleUI::PlayFile(Args args)
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleUI::Pause()
|
||||
{
|
||||
if (this->paused) {
|
||||
transport.Resume();
|
||||
this->paused = !this->paused;
|
||||
}
|
||||
else
|
||||
{
|
||||
transport.Pause();
|
||||
this->paused = !this->paused;
|
||||
}
|
||||
void ConsoleUI::Pause() {
|
||||
if (this->paused) {
|
||||
transport.Resume();
|
||||
this->paused = !this->paused;
|
||||
}
|
||||
else {
|
||||
transport.Pause();
|
||||
this->paused = !this->paused;
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleUI::Stop(Args args)
|
||||
{
|
||||
void ConsoleUI::Stop(Args args) {
|
||||
this->Stop();
|
||||
}
|
||||
|
||||
void ConsoleUI::Stop()
|
||||
{
|
||||
void ConsoleUI::Stop() {
|
||||
transport.Stop();
|
||||
}
|
||||
|
||||
void ConsoleUI::ListPlaying()
|
||||
{
|
||||
/*
|
||||
AudioStreamOverview overview = transport.StreamsOverview();
|
||||
AudioStreamOverviewIterator it;
|
||||
|
||||
|
||||
for (it = overview.begin(); it != overview.end(); ++it)
|
||||
{
|
||||
cout << *it << '\n';
|
||||
}
|
||||
void ConsoleUI::ListPlaying() {
|
||||
/*
|
||||
AudioStreamOverview overview = transport.StreamsOverview();
|
||||
AudioStreamOverviewIterator it;
|
||||
|
||||
cout << "------------------\n";
|
||||
cout << transport.NumOfStreams() << " playing" << std::std::endl;*/
|
||||
|
||||
for (it = overview.begin(); it != overview.end(); ++it) {
|
||||
cout << *it << '\n';
|
||||
}
|
||||
|
||||
cout << "------------------\n";
|
||||
cout << transport.NumOfStreams() << " playing" << std::std::endl;*/
|
||||
}
|
||||
|
||||
void ConsoleUI::ListPlugins()
|
||||
{
|
||||
void ConsoleUI::ListPlugins() {
|
||||
using musik::core::IPlugin;
|
||||
using musik::core::PluginFactory;
|
||||
|
||||
typedef std::vector<boost::shared_ptr<IPlugin> > PluginList;
|
||||
typedef PluginFactory::NullDeleter<IPlugin> Deleter;
|
||||
|
||||
PluginList plugins =
|
||||
PluginFactory::Instance().QueryInterface<IPlugin, Deleter>("GetPlugin");
|
||||
PluginList plugins = PluginFactory::Instance()
|
||||
.QueryInterface<IPlugin, Deleter>("GetPlugin");
|
||||
|
||||
PluginList::iterator it = plugins.begin();
|
||||
for ( ; it != plugins.end(); it++)
|
||||
{
|
||||
cout << (*it)->Name() << '\t' << (*it)->Version() << '\t' << (*it)->Author() << '\n';
|
||||
for ( ; it != plugins.end(); it++) {
|
||||
cout << (*it)->Name() << '\t' <<
|
||||
(*it)->Version() << '\t' <<
|
||||
(*it)->Author() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleUI::SetPosition(Args args)
|
||||
{
|
||||
if (args.size() > 0) {
|
||||
double newPosition = 0;
|
||||
if (convertString<double>(newPosition, args[0])) {
|
||||
transport.SetPosition(newPosition);
|
||||
}
|
||||
}
|
||||
void ConsoleUI::SetPosition(Args args) {
|
||||
if (args.size() > 0) {
|
||||
double newPosition = 0;
|
||||
if (tostr<double>(newPosition, args[0])) {
|
||||
transport.SetPosition(newPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleUI::SetVolume(Args args)
|
||||
{
|
||||
if (args.size() > 0)
|
||||
{
|
||||
void ConsoleUI::SetVolume(Args args) {
|
||||
if (args.size() > 0) {
|
||||
float newVolume = 0;
|
||||
if (convertString<float>(newVolume, args[0]))
|
||||
{
|
||||
if (tostr<float>(newVolume, args[0])) {
|
||||
this->SetVolume(newVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleUI::SetVolume(float volume)
|
||||
{
|
||||
void ConsoleUI::SetVolume(float volume) {
|
||||
transport.SetVolume(volume);
|
||||
}
|
||||
|
||||
void ConsoleUI::Quit()
|
||||
{
|
||||
void ConsoleUI::Quit() {
|
||||
this->shouldQuit = true;
|
||||
}
|
||||
|
||||
void ConsoleUI::ShutDown()
|
||||
{
|
||||
void ConsoleUI::ShutDown() {
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
/*static*/ DWORD WINAPI ConsoleUI::ThreadRun(LPVOID param)
|
||||
{
|
||||
ConsoleUI* instance = (ConsoleUI*)param;
|
||||
/*static*/ DWORD WINAPI ConsoleUI::ThreadRun(LPVOID param) {
|
||||
ConsoleUI* instance = (ConsoleUI*) param;
|
||||
instance->Run();
|
||||
delete instance;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ConsoleUI::StartNew()
|
||||
{
|
||||
Args a;
|
||||
this->PlayFile(a);
|
||||
}
|
||||
|
@ -38,12 +38,10 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <core/log/debug.h>
|
||||
#include <core/playback/Transport.h>
|
||||
|
||||
#include "DummyAudioEventHandler.h"
|
||||
#include "TransportEvents.h"
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
@ -51,55 +49,45 @@ class AudioStream;
|
||||
|
||||
namespace musik { namespace square {
|
||||
|
||||
typedef std::vector<std::string> Args;
|
||||
typedef std::vector<std::string> Args;
|
||||
|
||||
class ConsoleUI
|
||||
{
|
||||
public: ConsoleUI();
|
||||
public: ~ConsoleUI();
|
||||
class ConsoleUI : public sigslot::has_slots<> {
|
||||
public:
|
||||
ConsoleUI();
|
||||
~ConsoleUI();
|
||||
|
||||
public: void Run();
|
||||
private: void PrintCommands();
|
||||
private: void ProcessCommand(std::string commandString);
|
||||
public: void Print(std::string s);
|
||||
void Run();
|
||||
|
||||
// Commands
|
||||
private: void PlayFile(Args args);
|
||||
private: void Pause();
|
||||
private: void Stop(Args args);
|
||||
private: void Stop();
|
||||
private: void ListPlaying();
|
||||
private: void ListPlugins();
|
||||
private: void SetPosition(Args args);
|
||||
private: void SetVolume(Args args);
|
||||
private: void SetVolume(float volume);
|
||||
private: void Quit();
|
||||
private:
|
||||
void Help();
|
||||
void Process(const std::string& cmd);
|
||||
|
||||
// Members
|
||||
private: bool shouldQuit;
|
||||
private: bool paused;
|
||||
private: Transport transport;
|
||||
private: DummyAudioEventHandler audioEventHandler;
|
||||
void PlayFile(Args args);
|
||||
void Pause();
|
||||
void Stop(Args args);
|
||||
void Stop();
|
||||
void ListPlaying();
|
||||
void ListPlugins();
|
||||
void SetPosition(Args args);
|
||||
void SetVolume(Args args);
|
||||
void SetVolume(float volume);
|
||||
void Quit();
|
||||
|
||||
private: boost::mutex mutex;
|
||||
void OnDebug(musik::debug::log_level level, std::string tag, std::string message);
|
||||
|
||||
private: void ShutDown();
|
||||
bool shouldQuit;
|
||||
bool paused;
|
||||
Transport transport;
|
||||
TransportEvents audioEventHandler;
|
||||
|
||||
#ifdef WIN32
|
||||
public: static DWORD WINAPI ThreadRun(LPVOID param);
|
||||
#endif
|
||||
boost::mutex mutex;
|
||||
|
||||
public: void StartNew();
|
||||
};
|
||||
void ShutDown();
|
||||
|
||||
#ifdef WIN32
|
||||
public: static DWORD WINAPI ThreadRun(LPVOID param);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
}} // NS
|
||||
|
||||
// TODO: move to utility file
|
||||
#include <sstream>
|
||||
|
||||
template <class T>
|
||||
bool convertString(T& t, const std::string& s)
|
||||
{
|
||||
std::istringstream iss(s);
|
||||
return !(iss >> t).fail();
|
||||
}
|
||||
|
@ -32,29 +32,18 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "DummyAudioEventHandler.h"
|
||||
|
||||
#include "TransportEvents.h"
|
||||
#include "ConsoleUI.h"
|
||||
|
||||
using namespace musik::square;
|
||||
|
||||
DummyAudioEventHandler::DummyAudioEventHandler(ConsoleUI* c)
|
||||
: cui(c)
|
||||
{
|
||||
TransportEvents::TransportEvents(ConsoleUI* c)
|
||||
: cui(c) {
|
||||
}
|
||||
|
||||
DummyAudioEventHandler::~DummyAudioEventHandler()
|
||||
{
|
||||
TransportEvents::~TransportEvents() {
|
||||
}
|
||||
|
||||
void DummyAudioEventHandler::PrintEvent(std::string s)
|
||||
{
|
||||
this->cui->Print("EVENT: " + s + "\n");
|
||||
}
|
||||
|
||||
void DummyAudioEventHandler::OnMixpointReached()
|
||||
{
|
||||
this->PrintEvent("Mix point reached");
|
||||
//this->cui->StartNew(); // Endless test loop
|
||||
}
|
||||
void TransportEvents::LogEvent(std::string s) {
|
||||
musik::debug::log("playback", s);
|
||||
}
|
@ -34,41 +34,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <sigslot/sigslot.h>
|
||||
|
||||
namespace musik { namespace square {
|
||||
|
||||
class ConsoleUI;
|
||||
class ConsoleUI;
|
||||
|
||||
//enum AudioStreamEvent;
|
||||
class TransportEvents : public sigslot::has_slots<> {
|
||||
public:
|
||||
TransportEvents(ConsoleUI* c);
|
||||
~TransportEvents();
|
||||
|
||||
class DummyAudioEventHandler : public sigslot::has_slots<>
|
||||
{
|
||||
public: DummyAudioEventHandler(ConsoleUI* c);
|
||||
public: ~DummyAudioEventHandler();
|
||||
void OnPlaybackAlmostEnded() { this->LogEvent("about to end"); };
|
||||
void OnPlaybackStartedOk() { this->LogEvent("started"); };
|
||||
void OnPlaybackStartedFail() { this->LogEvent("failed"); };
|
||||
void OnPlaybackStoppedOk() { this->LogEvent("stopped"); };
|
||||
void OnPlaybackStoppedFail() { this->LogEvent("stopped because of failure"); };
|
||||
void OnPlaybackInterrupted() { this->LogEvent("interrupted (??)"); };
|
||||
void OnVolumeChangedOk() { this->LogEvent("volume changed"); };
|
||||
void OnStreamOpenOk() { this->LogEvent("stream open ok"); };
|
||||
void OnStreamOpenFail() { this->LogEvent("stream open fail"); };
|
||||
void OnMixpointReached() { this->LogEvent("mix point reached"); }
|
||||
void OnSetPositionOk() { this->LogEvent("set position"); };
|
||||
void OnSetPositionFail() { this->LogEvent("set position failed"); };
|
||||
void OnPlaybackPaused() { this->LogEvent("paused"); };
|
||||
void OnPlaybackResumed() { this->LogEvent("resumed"); };
|
||||
|
||||
private: ConsoleUI* cui; // TODO: should probably be interface
|
||||
private: void PrintEvent(std::string s);
|
||||
private:
|
||||
ConsoleUI* cui;
|
||||
void LogEvent(std::string s);
|
||||
};
|
||||
|
||||
// Slots
|
||||
public: void OnPlaybackAlmostEnded() { this->PrintEvent("Playback almost done"); };
|
||||
public: void OnPlaybackStartedOk() { this->PrintEvent("Playback started OK"); };
|
||||
public: void OnPlaybackStartedFail() { this->PrintEvent("Playback started FAIL"); };
|
||||
public: void OnPlaybackStoppedOk() { this->PrintEvent("Playback stopped OK"); };
|
||||
public: void OnPlaybackStoppedFail() { this->PrintEvent("Playback stopped FAIL"); };
|
||||
public: void OnPlaybackInterrupted() { this->PrintEvent("Playback interrupted"); };
|
||||
public: void OnVolumeChangedOk() { this->PrintEvent("Volume changed OK"); };
|
||||
public: void OnVolumeChangedFail() { this->PrintEvent("Volume changed FAIL"); };
|
||||
public: void OnStreamOpenOk() { this->PrintEvent("Stream open OK"); };
|
||||
public: void OnStreamOpenFail() { this->PrintEvent("Stream open FAIL"); };
|
||||
public: void OnMixpointReached() ;
|
||||
public: void OnSetPositionOk() { this->PrintEvent("Set position OK"); };
|
||||
public: void OnSetPositionFail() { this->PrintEvent("Set position FAIL"); };
|
||||
};
|
||||
|
||||
}} // NS
|
||||
} }
|
@ -49,14 +49,17 @@ int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
/* the following allows boost::filesystem to use utf8 on Windows */
|
||||
//std::locale::global(boost::locale::generator().generate(""));
|
||||
std::locale locale = std::locale();
|
||||
std::locale utf8Locale(locale, new boost::filesystem::detail::utf8_codecvt_facet);
|
||||
boost::filesystem::path::imbue(utf8Locale);
|
||||
|
||||
musik::debug::init();
|
||||
|
||||
ConsoleUI* instance = new ConsoleUI();
|
||||
instance->Run();
|
||||
delete instance;
|
||||
|
||||
return 0;
|
||||
musik::debug::deinit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ConsoleUI.cpp" />
|
||||
<ClCompile Include="DummyAudioEventHandler.cpp" />
|
||||
<ClCompile Include="TransportEvents.cpp" />
|
||||
<ClCompile Include="player.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
@ -121,7 +121,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="config.h" />
|
||||
<ClInclude Include="ConsoleUI.h" />
|
||||
<ClInclude Include="DummyAudioEventHandler.h" />
|
||||
<ClInclude Include="TransportEvents.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -5,10 +5,6 @@
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
@ -18,28 +14,28 @@
|
||||
<ClCompile Include="ConsoleUI.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DummyAudioEventHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="player.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TransportEvents.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ConsoleUI.h">
|
||||
<Filter>Header Files</Filter>
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DummyAudioEventHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
<ClInclude Include="TransportEvents.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,8 +1 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// player.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
|
@ -1,18 +1,9 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
//#include <vld/vld.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include "config.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user