Skip to content

Commit

Permalink
Merge pull request #43 from Musicoll/dev/master
Browse files Browse the repository at this point in the history
Dev/master
  • Loading branch information
jean-millot authored Nov 15, 2016
2 parents 46abe87 + 4385709 commit 2a23f5b
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 99 deletions.
74 changes: 60 additions & 14 deletions Client/Source/KiwiApp_DspDeviceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,21 @@
#include "KiwiApp_StoredSettings.hpp"
#include "KiwiApp.hpp"

#include <juce_audio_utils/juce_audio_utils.h>

namespace kiwi
{

// ================================================================================ //
// DSP DEVICE MANAGER //
// ================================================================================ //

DspDeviceManager::DspDeviceManager() :
m_input_matrix(nullptr),
m_output_matrix(nullptr)
m_output_matrix(nullptr),
m_chains(),
m_is_playing(false),
m_mutex()
{
juce::ScopedPointer<juce::XmlElement> previous_settings(getGlobalProperties().getXmlValue("Audio Settings"));

Expand All @@ -39,9 +49,6 @@ namespace kiwi
{
initialiseWithDefaultDevices(2, 2);
}

//! @todo Find a way to initilise setups without launching audio device.
stopAudio();
}

DspDeviceManager::~DspDeviceManager()
Expand All @@ -56,10 +63,9 @@ namespace kiwi
{
if(std::find(m_chains.begin(), m_chains.end(), &chain) == m_chains.cend())
{
juce::AudioIODevice* device = getCurrentAudioDevice();

if (device && device->isPlaying())
if (m_is_playing)
{
juce::AudioIODevice * const device = getCurrentAudioDevice();
chain.prepare(device->getCurrentSampleRate(), device->getCurrentBufferSizeSamples());
}

Expand Down Expand Up @@ -88,23 +94,20 @@ namespace kiwi
void DspDeviceManager::startAudio()
{
addAudioCallback(this);

closeAudioDevice();
restartLastAudioDevice();

m_is_playing = true;
KiwiApp::commandStatusChanged();
}

void DspDeviceManager::stopAudio()
{
getCurrentAudioDevice()->stop();
removeAudioCallback(this);
m_is_playing = false;
KiwiApp::commandStatusChanged();
}

bool DspDeviceManager::isAudioOn() const
{
return getCurrentAudioDevice() ? getCurrentAudioDevice()->isPlaying() : false;
return m_is_playing;
};

void DspDeviceManager::addSignal(dsp::Buffer const& output_buffer)
Expand Down Expand Up @@ -136,7 +139,14 @@ namespace kiwi

for(dsp::Chain * chain : m_chains)
{
chain->prepare(sample_rate, buffer_size);
try
{
chain->prepare(sample_rate, buffer_size);
}
catch(dsp::LoopError & e)
{
KiwiApp::use().error(e.what());
}
}

// allocate input matrix
Expand Down Expand Up @@ -197,4 +207,40 @@ namespace kiwi
(*m_output_matrix)[i].fill(0);
}
}

// ================================================================================ //
// AUDIO SETTING WINDOW //
// ================================================================================ //

AudioSettingWindow::AudioSettingWindow(DspDeviceManager& device_manager):
Window("Audio Settings", juce::Colours::white, allButtons, false)
{
juce::AudioDeviceSelectorComponent* audio_settings =
new juce::AudioDeviceSelectorComponent(device_manager, 1, 20, 1, 20, false, false, false, true);

setContentOwned(audio_settings, false);
setResizable(false, false);

const juce::String windowState(getGlobalProperties().getValue("audio_setting_window"));

if (!windowState.isEmpty())
{
restoreWindowStateFromString(windowState);
}
else
{
setSize(300, 440);
setTopLeftPosition(10, 10);
}
}

void AudioSettingWindow::closeButtonPressed()
{
setVisible(false);
}

AudioSettingWindow::~AudioSettingWindow()
{
getGlobalProperties().setValue("audio_setting_window", getWindowStateAsString());
}
}
16 changes: 16 additions & 0 deletions Client/Source/KiwiApp_DspDeviceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#ifndef KIWI_APP_DSP_DEVICE_MANAGER_HPP_INCLUDED
#define KIWI_APP_DSP_DEVICE_MANAGER_HPP_INCLUDED

#include "KiwiApp_Window.hpp"

#include <KiwiDsp/KiwiDsp_Signal.hpp>
#include <KiwiDsp/KiwiDsp_Chain.hpp>
#include <KiwiEngine/KiwiEngine_AudioControler.hpp>
Expand Down Expand Up @@ -104,8 +106,22 @@ namespace kiwi
std::unique_ptr<dsp::Buffer> m_input_matrix;
std::unique_ptr<dsp::Buffer> m_output_matrix;
std::vector<dsp::Chain*> m_chains;
bool m_is_playing;
mutable std::mutex m_mutex;
};

// ================================================================================ //
// AUDIO SETTING WINDOW //
// ================================================================================ //

class AudioSettingWindow : public Window
{
public:
AudioSettingWindow(DspDeviceManager& device_manager);
~AudioSettingWindow();

void closeButtonPressed() override;
};
}

#endif // KIWI_APP_DSP_DEVICE_MANAGER_HPP_INCLUDED
32 changes: 8 additions & 24 deletions Client/Source/KiwiApp_Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "KiwiApp.hpp"
#include "KiwiApp_Instance.hpp"
#include "KiwiApp_PatcherView.hpp"
#include "KiwiApp_DspDeviceManager.hpp"

#include "KiwiApp_Network/KiwiApp_DocumentManager.hpp"

Expand All @@ -46,6 +45,7 @@ namespace kiwi
m_console_window(new ConsoleWindow(m_console_history)),
m_document_browser_window(new DocumentBrowserWindow(m_server.getBrowser())),
m_beacon_dispatcher_window(new BeaconDispatcherWindow(m_instance)),
m_audio_setting_window(new AudioSettingWindow(dynamic_cast<DspDeviceManager&>(m_instance.getAudioControler()))),
m_last_opened_file(juce::File::getSpecialLocation(juce::File::userHomeDirectory))
{
m_server.run();
Expand Down Expand Up @@ -214,29 +214,6 @@ namespace kiwi
return nullptr;
}

// ================================================================================ //
// Audio Settings //
// ================================================================================ //

void Instance::showAudioSettingsWindow()
{
DspDeviceManager& device_manager = dynamic_cast<DspDeviceManager&>(m_instance.getAudioControler());
juce::AudioDeviceSelectorComponent audio_settings(device_manager, 1, 20, 1, 20, false, false, false, true);
juce::OptionalScopedPointer<juce::Component> settings_component(&audio_settings, false);

settings_component->setTopLeftPosition(10, 10);
settings_component->setSize(300, 440);
settings_component->setVisible(true);


juce::DialogWindow::LaunchOptions option;
option.dialogTitle = juce::String("Audio Settings");
option.content = settings_component;
option.resizable = true;

option.runModal();
}

Instance::PatcherManagers::iterator Instance::getPatcherManager(PatcherManager const& manager)
{
const auto find_it = [&manager](std::unique_ptr<PatcherManager> const& manager_uptr)
Expand Down Expand Up @@ -265,6 +242,13 @@ namespace kiwi
m_beacon_dispatcher_window->toFront(true);
}

void Instance::showAudioSettingsWindow()
{
m_audio_setting_window->addToDesktop();
m_audio_setting_window->setVisible(true);
m_audio_setting_window->toFront(true);
}

std::vector<uint8_t>& Instance::getPatcherClipboardData()
{
return m_patcher_clipboard;
Expand Down
4 changes: 3 additions & 1 deletion Client/Source/KiwiApp_Instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "KiwiApp_PatcherManager.hpp"
#include "KiwiApp_StoredSettings.hpp"
#include "KiwiApp_BeaconDispatcher.hpp"
#include "KiwiApp_DspDeviceManager.hpp"

#include "KiwiApp_Network/KiwiApp_Server.hpp"

Expand Down Expand Up @@ -117,7 +118,8 @@ namespace kiwi
std::unique_ptr<ConsoleWindow> m_console_window;
std::unique_ptr<DocumentBrowserWindow> m_document_browser_window;
std::unique_ptr<BeaconDispatcherWindow> m_beacon_dispatcher_window;

std::unique_ptr<AudioSettingWindow> m_audio_setting_window;

std::vector<uint8_t> m_patcher_clipboard;

static size_t m_untitled_patcher_index;
Expand Down
14 changes: 7 additions & 7 deletions Modules/KiwiDsp/KiwiDsp_Chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ namespace kiwi
m_commands.pop_front();
}

if (prev_state == State::Prepared)
if (prev_state == State::Prepared || prev_state == State::Preparing)
{
prepare(prev_samplerate, prev_vectorsize);
}
Expand All @@ -351,19 +351,19 @@ namespace kiwi

void Chain::prepare(const size_t samplerate, const size_t vector_size)
{
m_state = State::NotPrepared;

release();

update();

indexNodes();

sortNodes();
m_state = State::Preparing;

m_sample_rate = samplerate;
m_vector_size = vector_size;

indexNodes();

sortNodes();

for(auto node = m_nodes.begin(); node != m_nodes.end();)
{
if ((*node)->prepare(*this))
Expand Down Expand Up @@ -523,7 +523,7 @@ namespace kiwi
{
if (m_loop_nodes.find(&parent_node) != m_loop_nodes.end())
{
throw Error("A loop is detected");
throw LoopError("A loop is detected");
}
else
{
Expand Down
30 changes: 28 additions & 2 deletions Modules/KiwiDsp/KiwiDsp_Chain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <queue>

#include "KiwiDsp_Processor.hpp"
#include "KiwiDsp_Misc.hpp"

namespace kiwi
{
Expand Down Expand Up @@ -127,8 +128,9 @@ namespace kiwi
//! @details If chain is not prepared tick will do nothing.
enum class State : uint8_t
{
NotPrepared = 0, ///< The Node has not been prepared.
Prepared = 1, ///< The Node has been prepared.
NotPrepared = 0, ///< The Chain has not been prepared.
Preparing = 1, ///< The Chain is being prepared.
Prepared = 2, ///< The chain has been prepared.
};

class Node;
Expand Down Expand Up @@ -352,6 +354,30 @@ namespace kiwi

Tie() = delete;
};

// ==================================================================================== //
// LOOPERROR //
// ==================================================================================== //
//! @brief An exception to detect loops.
//! @details An exception that is thrown whenever a loop is detected in a chain.
//! @todo Add more infos about the detected loop.
class LoopError : public Error
{
public:
//! @brief The std::string constructor.
//! @param message The message of the error
explicit LoopError(const std::string& message) :
Error("looperror: " + message)
{}

//! @brief The const char* constructor.
//! @param message The message of the error
explicit LoopError(const char* message) :
Error(std::string("looperror: ") + std::string(message)) {}

//! @brief The destructor.
~LoopError() noexcept override = default;
};
}
}

Expand Down
Loading

0 comments on commit 2a23f5b

Please sign in to comment.