The beginnings of a logging infrastructure and a few more bug fixes and

cleanups.
This commit is contained in:
casey 2016-05-06 02:22:06 -07:00
parent e7fec08771
commit 1eee0ed459
17 changed files with 445 additions and 314 deletions

View File

@ -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>

View File

@ -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" />

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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
View 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
View 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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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
} }

View File

@ -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;
}

View File

@ -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>

View File

@ -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>

View File

@ -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

View 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