Last active
April 20, 2020 05:04
-
-
Save COx2/e51455828f580711779e0b7900b5476a to your computer and use it in GitHub Desktop.
JUCEのAudioDeviceManagerに独自のAudioDeviceを追加する
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
============================================================================== | |
This file was auto-generated! | |
============================================================================== | |
*/ | |
#include "MainComponent.h" | |
#include "MyAudioDevice.h" | |
//============================================================================== | |
MainComponent::MainComponent() | |
{ | |
deviceManager.addAudioDeviceType(new SineWaveAudioIODeviceType()); | |
setSize(800, 600); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
============================================================================== | |
MyAudioDevice.cpp | |
Created: 11 Jul 2019 3:50:56pm | |
Author: COx2 | |
============================================================================== | |
*/ | |
#include "MyAudioDevice.h" | |
//============================================================================== | |
SineWaveAudioIODevice::SineWaveAudioIODevice(const String & deviceName, const String & typeName, const String & outputDeviceID, const String & inputDeviceID) | |
: AudioIODevice(deviceName, typeName) | |
{ | |
} | |
SineWaveAudioIODevice::~SineWaveAudioIODevice() | |
{ | |
} | |
Array<double> SineWaveAudioIODevice::getAvailableSampleRates() | |
{ | |
Array<double> ret; | |
ret.add(44100); | |
ret.add(48000); | |
ret.add(88200); | |
ret.add(96000); | |
return ret; | |
} | |
Array<int> SineWaveAudioIODevice::getAvailableBufferSizes() | |
{ | |
Array<int> ret; | |
ret.add(256); | |
ret.add(512); | |
ret.add(1024); | |
return ret; | |
} | |
int SineWaveAudioIODevice::getDefaultBufferSize() | |
{ | |
return bufferSize; | |
} | |
String SineWaveAudioIODevice::open(const BigInteger & inputChannels, const BigInteger & outputChannels, double sampleRate_, int bufferSizeSamples) | |
{ | |
ScopedLock lock(audioDeviceLock); | |
sampleRate = sampleRate_; | |
channelsIn = inputChannels; | |
channelsOut = outputChannels; | |
bufferSize = bufferSizeSamples; | |
numChannelsIn = channelsIn.countNumberOfSetBits(); | |
numChannelsOut = channelsOut.countNumberOfSetBits(); | |
closed = false; | |
return String(); | |
} | |
void SineWaveAudioIODevice::close() | |
{ | |
stop(); | |
closed = true; | |
} | |
bool SineWaveAudioIODevice::isOpen() | |
{ | |
return ! closed; | |
} | |
void SineWaveAudioIODevice::start(AudioIODeviceCallback * callback) | |
{ | |
deviceManagerCallbackHandler = callback; | |
deviceManagerCallbackHandler->audioDeviceAboutToStart(this); | |
startTimerHz(30); | |
} | |
void SineWaveAudioIODevice::stop() | |
{ | |
if (deviceManagerCallbackHandler != nullptr) | |
{ | |
ScopedLock lock(audioDeviceLock); | |
stopTimer(); | |
deviceManagerCallbackHandler->audioDeviceStopped(); | |
deviceManagerCallbackHandler = nullptr; | |
} | |
} | |
bool SineWaveAudioIODevice::isPlaying() | |
{ | |
return deviceManagerCallbackHandler != nullptr; | |
} | |
String SineWaveAudioIODevice::getLastError() | |
{ | |
return String(); | |
} | |
void SineWaveAudioIODevice::timerCallback() | |
{ | |
AudioBuffer<float> inputBuffer(numChannelsIn, bufferSize); | |
AudioBuffer<float> outputBuffer(numChannelsOut, bufferSize); | |
for (int ch_index = 0; ch_index < inputBuffer.getNumChannels(); ++ch_index) | |
{ | |
auto ch_data = inputBuffer.getWritePointer(ch_index); | |
for (int sample = 0; sample < inputBuffer.getNumSamples(); ++sample) | |
{ | |
ch_data[sample] = sinf(juce::MathConstants<float>::twoPi * sample / inputBuffer.getNumSamples()) * 0.5f; | |
} | |
} | |
deviceManagerCallbackHandler->audioDeviceIOCallback( | |
inputBuffer.getArrayOfReadPointers(), inputBuffer.getNumChannels(), | |
outputBuffer.getArrayOfWritePointers(), outputBuffer.getNumChannels(), | |
bufferSize | |
); | |
} | |
//============================================================================== | |
StringArray SineWaveAudioIODeviceType::getDeviceNames(bool wantInputNames) const | |
{ | |
if(wantInputNames) | |
return inputDeviceNames; | |
else | |
return outputDeviceNames; | |
} | |
int SineWaveAudioIODeviceType::getDefaultDeviceIndex(bool forInput) const | |
{ | |
return 0; | |
} | |
int SineWaveAudioIODeviceType::getIndexOfDevice(AudioIODevice * device, bool asInput) const | |
{ | |
if (asInput) | |
switch (device->getActiveInputChannels().getHighestBit()) | |
{ | |
case 0: | |
case 1: | |
return 0; | |
break; | |
case 2: | |
case 3: | |
return 1; | |
break; | |
default: | |
return -1; | |
break; | |
} | |
else | |
switch (device->getActiveOutputChannels().getHighestBit()) | |
{ | |
case 0: | |
case 1: | |
return 0; | |
break; | |
case 2: | |
case 3: | |
return 1; | |
break; | |
default: | |
return -1; | |
break; | |
} | |
} | |
AudioIODevice * SineWaveAudioIODeviceType::createDevice(const String & outputDeviceName, const String & inputDeviceName) | |
{ | |
DBG("SineWaveAudioIODeviceType::createDevice"); | |
std::unique_ptr<SineWaveAudioIODevice> device; | |
device.reset(new SineWaveAudioIODevice(outputDeviceName, getTypeName(), outputDeviceName, inputDeviceName)); | |
return device.release(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
============================================================================== | |
MyAudioDevice.h | |
Created: 11 Jul 2019 3:50:56pm | |
Author: COx2 | |
============================================================================== | |
*/ | |
#pragma once | |
#include "../JuceLibraryCode/JuceHeader.h" | |
class SineWaveAudioIODevice : public AudioIODevice, private Timer | |
{ | |
public: | |
SineWaveAudioIODevice(const String& deviceName, const String& typeName, const String& outputDeviceID, const String& inputDeviceID); | |
~SineWaveAudioIODevice() override; | |
virtual StringArray getOutputChannelNames() override { return { "Out1", "Out2", "Out3", "Out4" }; }; | |
virtual StringArray getInputChannelNames() override { return{ "In1", "In2", "In3", "In4" }; }; | |
virtual Array<double> getAvailableSampleRates() override; | |
virtual Array<int> getAvailableBufferSizes() override; | |
virtual int getDefaultBufferSize() override; | |
virtual String open(const BigInteger& inputChannels, const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) override; | |
virtual void close() override; | |
virtual bool isOpen() override; | |
virtual void start(AudioIODeviceCallback* callback) override; | |
virtual void stop() override; | |
virtual bool isPlaying() override; | |
virtual String getLastError() override; | |
//============================================================================== | |
virtual int getCurrentBufferSizeSamples() override { return bufferSize; }; | |
virtual double getCurrentSampleRate() override { return sampleRate; }; | |
virtual int getCurrentBitDepth() override { return bitDepth; }; | |
virtual BigInteger getActiveOutputChannels() const override { return channelsOut; }; | |
virtual BigInteger getActiveInputChannels() const override { return channelsIn; }; | |
virtual int getOutputLatencyInSamples() override { return 0; }; | |
virtual int getInputLatencyInSamples() override { return 0; }; | |
private: | |
virtual void timerCallback() override; | |
int bufferSize{ 512 }; | |
double sampleRate{ 44100 }; | |
int bitDepth{ 32 }; | |
BigInteger channelsIn, channelsOut; | |
int numChannelsIn, numChannelsOut; | |
CriticalSection audioDeviceLock; | |
bool closed{ false }; | |
// AudioDeviceMangerで保持しているコールバック先のオブジェクト | |
AudioIODeviceCallback* deviceManagerCallbackHandler{ nullptr }; | |
}; | |
class SineWaveAudioIODeviceType : public AudioIODeviceType | |
{ | |
public: | |
SineWaveAudioIODeviceType() | |
: AudioIODeviceType("SineWave Audio Device") | |
{}; | |
~SineWaveAudioIODeviceType() override | |
{}; | |
virtual void scanForDevices() override {} | |
virtual StringArray getDeviceNames(bool wantInputNames = false) const override; | |
virtual int getDefaultDeviceIndex(bool forInput) const override; | |
virtual int getIndexOfDevice(AudioIODevice* device, bool asInput) const override; | |
virtual bool hasSeparateInputsAndOutputs() const override { return true; }; | |
virtual AudioIODevice* createDevice(const String& outputDeviceName, const String& inputDeviceName) override; | |
private: | |
StringArray inputDeviceNames { "SineWave Input1", "SineWave Input2" }; | |
StringArray outputDeviceNames{ "SineWave Output1", "SineWave Output2" }; | |
}; |
I am beginner to CPP. How to solve this:
Severity Code Description Project File Line Suppression State
Error C2664 'void juce::AudioDeviceManager::addAudioDeviceType(std::unique_ptr<juce::AudioIODeviceType,std::default_delete<_Ty>>)': cannot convert argument 1 from 'SineWaveAudioIODeviceType *' to 'std::unique_ptr<juce::AudioIODeviceType,std::default_delete<_Ty>>' AudioPluginHost_App c:\juce\extras\audiopluginhost\source\ui\mainhostwindow.cpp 555
@meteorsnows
I think you use an upper version of JUCE library than my gist used.
I think If you rewrite your code like below, it will be good.
https://gist.github.com/COx2/e51455828f580711779e0b7900b5476a#file-maincomponent-cpp-L16
deviceManager.addAudioDeviceType(std::make_unique<SineWaveAudioIODeviceType>());
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
AudioIODeviceとAudioIODeviceTypeをそれぞれ継承して、AudioDeviceManagerに追加すれば、JUCEのデザインパターンに組み込まれるような仕組みになっている。
AudioIODevice...NativeなオーディオAPIの実装を書く
AudioIODeviceType...AudioIODeviceの”型情報”みたいなもの。インスタンス生成・メタ情報を司る