Compare commits

...

10 Commits

45 changed files with 717 additions and 742 deletions

View File

@ -8,40 +8,37 @@
//#include <etk/types.hpp> //#include <etk/types.hpp>
#include <audio/orchestra/Interface.hpp> #include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <iostream> #include <etk/types.hpp>
#include <cstdlib>
#include <cstring>
#include <climits>
// Static variable definitions. // Static variable definitions.
const std::vector<uint32_t>& audio::orchestra::genericSampleRate() { const etk::Vector<uint32_t>& audio::orchestra::genericSampleRate() {
static std::vector<uint32_t> list; static etk::Vector<uint32_t> list;
if (list.size() == 0) { if (list.size() == 0) {
list.push_back(4000); list.pushBack(4000);
list.push_back(5512); list.pushBack(5512);
list.push_back(8000); list.pushBack(8000);
list.push_back(9600); list.pushBack(9600);
list.push_back(11025); list.pushBack(11025);
list.push_back(16000); list.pushBack(16000);
list.push_back(22050); list.pushBack(22050);
list.push_back(32000); list.pushBack(32000);
list.push_back(44100); list.pushBack(44100);
list.push_back(48000); list.pushBack(48000);
list.push_back(64000); list.pushBack(64000);
list.push_back(88200); list.pushBack(88200);
list.push_back(96000); list.pushBack(96000);
list.push_back(128000); list.pushBack(128000);
list.push_back(176400); list.pushBack(176400);
list.push_back(192000); list.pushBack(192000);
list.push_back(256000); list.pushBack(256000);
} }
return list; return list;
}; };
audio::orchestra::Api::Api() : audio::orchestra::Api::Api() :
m_callback(nullptr), m_callback(null),
m_deviceBuffer(nullptr) { m_deviceBuffer(null) {
m_device[0] = 11111; m_device[0] = 11111;
m_device[1] = 11111; m_device[1] = 11111;
m_state = audio::orchestra::state::closed; m_state = audio::orchestra::state::closed;
@ -55,7 +52,7 @@ audio::orchestra::Api::~Api() {
enum audio::orchestra::error audio::orchestra::Api::startStream() { enum audio::orchestra::error audio::orchestra::Api::startStream() {
ATA_VERBOSE("Start Stream"); ATA_VERBOSE("Start Stream");
m_startTime = audio::Time::now(); m_startTime = audio::Time::now();
m_duration = std::chrono::microseconds(0); m_duration = echrono::microseconds(0);
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
@ -70,19 +67,19 @@ enum audio::orchestra::error audio::orchestra::Api::openStream(audio::orchestra:
ATA_ERROR("a stream is already open!"); ATA_ERROR("a stream is already open!");
return audio::orchestra::error_invalidUse; return audio::orchestra::error_invalidUse;
} }
if ( _oParams != nullptr if ( _oParams != null
&& _oParams->nChannels < 1) { && _oParams->nChannels < 1) {
ATA_ERROR("a non-nullptr output StreamParameters structure cannot have an nChannels value less than one."); ATA_ERROR("a non-null output StreamParameters structure cannot have an nChannels value less than one.");
return audio::orchestra::error_invalidUse; return audio::orchestra::error_invalidUse;
} }
if ( _iParams != nullptr if ( _iParams != null
&& _iParams->nChannels < 1) { && _iParams->nChannels < 1) {
ATA_ERROR("a non-nullptr input StreamParameters structure cannot have an nChannels value less than one."); ATA_ERROR("a non-null input StreamParameters structure cannot have an nChannels value less than one.");
return audio::orchestra::error_invalidUse; return audio::orchestra::error_invalidUse;
} }
if ( _oParams == nullptr if ( _oParams == null
&& _iParams == nullptr) { && _iParams == null) {
ATA_ERROR("input and output StreamParameters structures are both nullptr!"); ATA_ERROR("input and output StreamParameters structures are both null!");
return audio::orchestra::error_invalidUse; return audio::orchestra::error_invalidUse;
} }
if (audio::getFormatBytes(_format) == 0) { if (audio::getFormatBytes(_format) == 0) {
@ -91,7 +88,7 @@ enum audio::orchestra::error audio::orchestra::Api::openStream(audio::orchestra:
} }
uint32_t nDevices = getDeviceCount(); uint32_t nDevices = getDeviceCount();
uint32_t oChannels = 0; uint32_t oChannels = 0;
if (_oParams != nullptr) { if (_oParams != null) {
oChannels = _oParams->nChannels; oChannels = _oParams->nChannels;
if ( _oParams->deviceId >= nDevices if ( _oParams->deviceId >= nDevices
&& _oParams->deviceName == "") { && _oParams->deviceName == "") {
@ -100,7 +97,7 @@ enum audio::orchestra::error audio::orchestra::Api::openStream(audio::orchestra:
} }
} }
uint32_t iChannels = 0; uint32_t iChannels = 0;
if (_iParams != nullptr) { if (_iParams != null) {
iChannels = _iParams->nChannels; iChannels = _iParams->nChannels;
if ( _iParams->deviceId >= nDevices if ( _iParams->deviceId >= nDevices
&& _iParams->deviceName == "") { && _iParams->deviceName == "") {
@ -250,8 +247,8 @@ void audio::orchestra::Api::clearStreamInfo() {
m_userFormat = audio::format_unknow; m_userFormat = audio::format_unknow;
m_startTime = audio::Time(); m_startTime = audio::Time();
m_duration = audio::Duration(0); m_duration = audio::Duration(0);
m_deviceBuffer = nullptr; m_deviceBuffer = null;
m_callback = nullptr; m_callback = null;
for (int32_t iii=0; iii<2; ++iii) { for (int32_t iii=0; iii<2; ++iii) {
m_device[iii] = 11111; m_device[iii] = 11111;
m_doConvertBuffer[iii] = false; m_doConvertBuffer[iii] = false;
@ -295,21 +292,21 @@ void audio::orchestra::Api::setConvertInfo(audio::orchestra::mode _mode, uint32_
if (m_deviceInterleaved[idTable] == false) { if (m_deviceInterleaved[idTable] == false) {
if (_mode == audio::orchestra::mode_input) { if (_mode == audio::orchestra::mode_input) {
for (int32_t kkk=0; kkk<m_convertInfo[idTable].channels; ++kkk) { for (int32_t kkk=0; kkk<m_convertInfo[idTable].channels; ++kkk) {
m_convertInfo[idTable].inOffset.push_back(kkk * m_bufferSize); m_convertInfo[idTable].inOffset.pushBack(kkk * m_bufferSize);
m_convertInfo[idTable].outOffset.push_back(kkk); m_convertInfo[idTable].outOffset.pushBack(kkk);
m_convertInfo[idTable].inJump = 1; m_convertInfo[idTable].inJump = 1;
} }
} else { } else {
for (int32_t kkk=0; kkk<m_convertInfo[idTable].channels; ++kkk) { for (int32_t kkk=0; kkk<m_convertInfo[idTable].channels; ++kkk) {
m_convertInfo[idTable].inOffset.push_back(kkk); m_convertInfo[idTable].inOffset.pushBack(kkk);
m_convertInfo[idTable].outOffset.push_back(kkk * m_bufferSize); m_convertInfo[idTable].outOffset.pushBack(kkk * m_bufferSize);
m_convertInfo[idTable].outJump = 1; m_convertInfo[idTable].outJump = 1;
} }
} }
} else { // no (de)interleaving } else { // no (de)interleaving
for (int32_t kkk=0; kkk<m_convertInfo[idTable].channels; ++kkk) { for (int32_t kkk=0; kkk<m_convertInfo[idTable].channels; ++kkk) {
m_convertInfo[idTable].inOffset.push_back(kkk); m_convertInfo[idTable].inOffset.pushBack(kkk);
m_convertInfo[idTable].outOffset.push_back(kkk); m_convertInfo[idTable].outOffset.pushBack(kkk);
} }
} }

View File

@ -6,7 +6,7 @@
*/ */
#pragma once #pragma once
#include <sstream> #include <etk/Stream.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <audio/orchestra/type.hpp> #include <audio/orchestra/type.hpp>
#include <audio/orchestra/state.hpp> #include <audio/orchestra/state.hpp>
@ -22,22 +22,22 @@ namespace audio {
* @brief Audio-orchestra library namespace * @brief Audio-orchestra library namespace
*/ */
namespace orchestra { namespace orchestra {
const std::vector<uint32_t>& genericSampleRate(); const etk::Vector<uint32_t>& genericSampleRate();
/** /**
* @brief airtaudio callback function prototype. * @brief airtaudio callback function prototype.
* @param _inputBuffer For input (or duplex) streams, this buffer will hold _nbChunk of input audio chunk (nullptr if no data). * @param _inputBuffer For input (or duplex) streams, this buffer will hold _nbChunk of input audio chunk (null if no data).
* @param _timeInput Timestamp of the first buffer sample (recording time). * @param _timeInput Timestamp of the first buffer sample (recording time).
* @param _outputBuffer For output (or duplex) streams, the client should write _nbChunk of audio chunk into this buffer (nullptr if no data). * @param _outputBuffer For output (or duplex) streams, the client should write _nbChunk of audio chunk into this buffer (null if no data).
* @param _timeOutput Timestamp of the first buffer sample (playing time). * @param _timeOutput Timestamp of the first buffer sample (playing time).
* @param _nbChunk The number of chunk of input or output chunk in the buffer (same size). * @param _nbChunk The number of chunk of input or output chunk in the buffer (same size).
* @param _status List of error that occured in the laps of time. * @param _status List of error that occured in the laps of time.
*/ */
typedef std::function<int32_t (const void* _inputBuffer, typedef etk::Function<int32_t (const void* _inputBuffer,
const audio::Time& _timeInput, const audio::Time& _timeInput,
void* _outputBuffer, void* _outputBuffer,
const audio::Time& _timeOutput, const audio::Time& _timeOutput,
uint32_t _nbChunk, uint32_t _nbChunk,
const std::vector<audio::orchestra::status>& _status)> AirTAudioCallback; const etk::Vector<audio::orchestra::status>& _status)> AirTAudioCallback;
// A protected structure used for buffer conversion. // A protected structure used for buffer conversion.
class ConvertInfo { class ConvertInfo {
public: public:
@ -46,24 +46,24 @@ namespace audio {
int32_t outJump; int32_t outJump;
enum audio::format inFormat; enum audio::format inFormat;
enum audio::format outFormat; enum audio::format outFormat;
std::vector<int> inOffset; etk::Vector<int> inOffset;
std::vector<int> outOffset; etk::Vector<int> outOffset;
}; };
class Api : public ememory::EnableSharedFromThis<Api>{ class Api : public ememory::EnableSharedFromThis<Api>{
protected: protected:
std::string m_name; etk::String m_name;
public: public:
Api(); Api();
virtual ~Api(); virtual ~Api();
void setName(const std::string& _name) { void setName(const etk::String& _name) {
m_name = _name; m_name = _name;
} }
virtual const std::string& getCurrentApi() = 0; virtual const etk::String& getCurrentApi() = 0;
virtual uint32_t getDeviceCount() = 0; virtual uint32_t getDeviceCount() = 0;
virtual audio::orchestra::DeviceInfo getDeviceInfo(uint32_t _device) = 0; virtual audio::orchestra::DeviceInfo getDeviceInfo(uint32_t _device) = 0;
// TODO : Check API ... // TODO : Check API ...
virtual bool getNamedDeviceInfo(const std::string& _deviceName, audio::orchestra::DeviceInfo& _info) { virtual bool getNamedDeviceInfo(const etk::String& _deviceName, audio::orchestra::DeviceInfo& _info) {
return false; return false;
} }
virtual uint32_t getDefaultInputDevice(); virtual uint32_t getDefaultInputDevice();
@ -90,12 +90,12 @@ namespace audio {
} }
protected: protected:
mutable std::mutex m_mutex; mutable ethread::Mutex m_mutex;
audio::orchestra::AirTAudioCallback m_callback; audio::orchestra::AirTAudioCallback m_callback;
uint32_t m_device[2]; // Playback and record, respectively. uint32_t m_device[2]; // Playback and record, respectively.
enum audio::orchestra::mode m_mode; // audio::orchestra::mode_output, audio::orchestra::mode_input, or audio::orchestra::mode_duplex. enum audio::orchestra::mode m_mode; // audio::orchestra::mode_output, audio::orchestra::mode_input, or audio::orchestra::mode_duplex.
enum audio::orchestra::state m_state; // STOPPED, RUNNING, or CLOSED enum audio::orchestra::state m_state; // STOPPED, RUNNING, or CLOSED
std::vector<char> m_userBuffer[2]; // Playback and record, respectively. etk::Vector<char> m_userBuffer[2]; // Playback and record, respectively.
char *m_deviceBuffer; char *m_deviceBuffer;
bool m_doConvertBuffer[2]; // Playback and record, respectively. bool m_doConvertBuffer[2]; // Playback and record, respectively.
bool m_deviceInterleaved[2]; // Playback and record, respectively. bool m_deviceInterleaved[2]; // Playback and record, respectively.
@ -130,7 +130,7 @@ namespace audio {
enum audio::format _format, enum audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
const audio::orchestra::StreamOptions& _options); const audio::orchestra::StreamOptions& _options);
virtual bool openName(const std::string& _deviceName, virtual bool openName(const etk::String& _deviceName,
audio::orchestra::mode _mode, audio::orchestra::mode _mode,
uint32_t _channels, uint32_t _channels,
uint32_t _firstChannel, uint32_t _firstChannel,

View File

@ -9,10 +9,9 @@
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <audio/orchestra/DeviceInfo.hpp> #include <audio/orchestra/DeviceInfo.hpp>
#include <etk/stdTools.hpp> #include <etk/stdTools.hpp>
#include <iostream>
void audio::orchestra::DeviceInfo::display(int32_t _tabNumber) const { void audio::orchestra::DeviceInfo::display(int32_t _tabNumber) const {
std::string space; etk::String space;
for (int32_t iii=0; iii<_tabNumber; ++iii) { for (int32_t iii=0; iii<_tabNumber; ++iii) {
space += " "; space += " ";
} }
@ -42,7 +41,7 @@ void audio::orchestra::DeviceInfo::clear() {
isDefault = false; isDefault = false;
} }
std::ostream& audio::orchestra::operator <<(std::ostream& _os, const audio::orchestra::DeviceInfo& _obj) { etk::Stream& audio::orchestra::operator <<(etk::Stream& _os, const audio::orchestra::DeviceInfo& _obj) {
_os << "{"; _os << "{";
if (_obj.isCorrect == false) { if (_obj.isCorrect == false) {
_os << "NOT CORRECT INFORAMATIONS"; _os << "NOT CORRECT INFORAMATIONS";

View File

@ -18,11 +18,11 @@ namespace audio {
public: public:
bool isCorrect; //!< the information is correct (the system can return information incorect). bool isCorrect; //!< the information is correct (the system can return information incorect).
bool input; //!< true if the device in an input; false: output. bool input; //!< true if the device in an input; false: output.
std::string name; //!< Character string device identifier. etk::String name; //!< Character string device identifier.
std::string desc; //!< description of the device etk::String desc; //!< description of the device
std::vector<audio::channel> channels; //!< Channels interfaces. etk::Vector<audio::channel> channels; //!< Channels interfaces.
std::vector<uint32_t> sampleRates; //!< Supported sample rates (queried from list of standard rates). etk::Vector<uint32_t> sampleRates; //!< Supported sample rates (queried from list of standard rates).
std::vector<audio::format> nativeFormats; //!< Bit mask of supported data formats. etk::Vector<audio::format> nativeFormats; //!< Bit mask of supported data formats.
bool isDefault; //! is default input/output bool isDefault; //! is default input/output
// Default constructor. // Default constructor.
DeviceInfo() : DeviceInfo() :
@ -43,7 +43,7 @@ namespace audio {
*/ */
void clear(); void clear();
}; };
std::ostream& operator <<(std::ostream& _os, const audio::orchestra::DeviceInfo& _obj); etk::Stream& operator <<(etk::Stream& _os, const audio::orchestra::DeviceInfo& _obj);
} }
} }

View File

@ -8,7 +8,6 @@
//#include <etk/types.hpp> //#include <etk/types.hpp>
#include <audio/orchestra/Interface.hpp> #include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <iostream>
#include <audio/orchestra/api/Alsa.hpp> #include <audio/orchestra/api/Alsa.hpp>
#include <audio/orchestra/api/Android.hpp> #include <audio/orchestra/api/Android.hpp>
#include <audio/orchestra/api/Asio.hpp> #include <audio/orchestra/api/Asio.hpp>
@ -19,26 +18,26 @@
#include <audio/orchestra/api/Jack.hpp> #include <audio/orchestra/api/Jack.hpp>
#include <audio/orchestra/api/Pulse.hpp> #include <audio/orchestra/api/Pulse.hpp>
std::vector<std::string> audio::orchestra::Interface::getListApi() { etk::Vector<etk::String> audio::orchestra::Interface::getListApi() {
std::vector<std::string> apis; etk::Vector<etk::String> apis;
// The order here will control the order of RtAudio's API search in // The order here will control the order of RtAudio's API search in
// the constructor. // the constructor.
for (size_t iii=0; iii<m_apiAvaillable.size(); ++iii) { for (size_t iii=0; iii<m_apiAvaillable.size(); ++iii) {
apis.push_back(m_apiAvaillable[iii].first); apis.pushBack(m_apiAvaillable[iii].first);
} }
return apis; return apis;
} }
void audio::orchestra::Interface::openApi(const std::string& _api) { void audio::orchestra::Interface::openApi(const etk::String& _api) {
m_api.reset(); m_api.reset();
for (size_t iii=0; iii<m_apiAvaillable.size(); ++iii) { for (size_t iii=0; iii<m_apiAvaillable.size(); ++iii) {
ATA_INFO("try open " << m_apiAvaillable[iii].first); ATA_INFO("try open " << m_apiAvaillable[iii].first);
if (_api == m_apiAvaillable[iii].first) { if (_api == m_apiAvaillable[iii].first) {
ATA_INFO(" ==> call it"); ATA_INFO(" ==> call it");
m_api = m_apiAvaillable[iii].second(); m_api = m_apiAvaillable[iii].second();
if (m_api != nullptr) { if (m_api != null) {
return; return;
} }
} }
@ -49,7 +48,7 @@ void audio::orchestra::Interface::openApi(const std::string& _api) {
audio::orchestra::Interface::Interface() : audio::orchestra::Interface::Interface() :
m_api(nullptr) { m_api(null) {
ATA_DEBUG("Add interface:"); ATA_DEBUG("Add interface:");
#if defined(ORCHESTRA_BUILD_JACK) #if defined(ORCHESTRA_BUILD_JACK)
addInterface(audio::orchestra::typeJack, audio::orchestra::api::Jack::create); addInterface(audio::orchestra::typeJack, audio::orchestra::api::Jack::create);
@ -80,13 +79,13 @@ audio::orchestra::Interface::Interface() :
#endif #endif
} }
void audio::orchestra::Interface::addInterface(const std::string& _api, ememory::SharedPtr<Api> (*_callbackCreate)()) { void audio::orchestra::Interface::addInterface(const etk::String& _api, ememory::SharedPtr<Api> (*_callbackCreate)()) {
m_apiAvaillable.push_back(std::pair<std::string, ememory::SharedPtr<Api> (*)()>(_api, _callbackCreate)); m_apiAvaillable.pushBack(etk::Pair<etk::String, ememory::SharedPtr<Api> (*)()>(_api, _callbackCreate));
} }
enum audio::orchestra::error audio::orchestra::Interface::clear() { enum audio::orchestra::error audio::orchestra::Interface::clear() {
ATA_INFO("Clear API ..."); ATA_INFO("Clear API ...");
if (m_api == nullptr) { if (m_api == null) {
ATA_WARNING("Interface NOT started!"); ATA_WARNING("Interface NOT started!");
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
@ -94,9 +93,9 @@ enum audio::orchestra::error audio::orchestra::Interface::clear() {
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
enum audio::orchestra::error audio::orchestra::Interface::instanciate(const std::string& _api) { enum audio::orchestra::error audio::orchestra::Interface::instanciate(const etk::String& _api) {
ATA_INFO("Instanciate API ..."); ATA_INFO("Instanciate API ...");
if (m_api != nullptr) { if (m_api != null) {
ATA_WARNING("Interface already started!"); ATA_WARNING("Interface already started!");
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
@ -104,7 +103,7 @@ enum audio::orchestra::error audio::orchestra::Interface::instanciate(const std:
ATA_INFO("API specified : " << _api); ATA_INFO("API specified : " << _api);
// Attempt to open the specified API. // Attempt to open the specified API.
openApi(_api); openApi(_api);
if (m_api != nullptr) { if (m_api != null) {
if (m_api->getDeviceCount() != 0) { if (m_api->getDeviceCount() != 0) {
ATA_INFO(" ==> api open"); ATA_INFO(" ==> api open");
} }
@ -118,12 +117,12 @@ enum audio::orchestra::error audio::orchestra::Interface::instanciate(const std:
ATA_INFO("Auto choice API :"); ATA_INFO("Auto choice API :");
// Iterate through the compiled APIs and return as soon as we find // Iterate through the compiled APIs and return as soon as we find
// one with at least one device or we reach the end of the list. // one with at least one device or we reach the end of the list.
std::vector<std::string> apis = getListApi(); etk::Vector<etk::String> apis = getListApi();
ATA_INFO(" find : " << apis.size() << " apis."); ATA_INFO(" find : " << apis.size() << " apis.");
for (size_t iii=0; iii<apis.size(); ++iii) { for (size_t iii=0; iii<apis.size(); ++iii) {
ATA_INFO("try open ..."); ATA_INFO("try open ...");
openApi(apis[iii]); openApi(apis[iii]);
if(m_api == nullptr) { if(m_api == null) {
ATA_ERROR(" ==> can not create ..."); ATA_ERROR(" ==> can not create ...");
continue; continue;
} }
@ -134,7 +133,7 @@ enum audio::orchestra::error audio::orchestra::Interface::instanciate(const std:
ATA_INFO(" ==> Interface exist, but have no devices: " << m_api->getDeviceCount()); ATA_INFO(" ==> Interface exist, but have no devices: " << m_api->getDeviceCount());
} }
} }
if (m_api != nullptr) { if (m_api != null) {
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
ATA_ERROR("API NOT Supported '" << _api << "' not in " << getListApi()); ATA_ERROR("API NOT Supported '" << _api << "' not in " << getListApi());
@ -153,7 +152,7 @@ enum audio::orchestra::error audio::orchestra::Interface::openStream(audio::orch
uint32_t* _bufferFrames, uint32_t* _bufferFrames,
audio::orchestra::AirTAudioCallback _callback, audio::orchestra::AirTAudioCallback _callback,
const audio::orchestra::StreamOptions& _options) { const audio::orchestra::StreamOptions& _options) {
if (m_api == nullptr) { if (m_api == null) {
return audio::orchestra::error_inputNull; return audio::orchestra::error_inputNull;
} }
return m_api->openStream(_outputParameters, return m_api->openStream(_outputParameters,
@ -166,12 +165,12 @@ enum audio::orchestra::error audio::orchestra::Interface::openStream(audio::orch
} }
bool audio::orchestra::Interface::isMasterOf(audio::orchestra::Interface& _interface) { bool audio::orchestra::Interface::isMasterOf(audio::orchestra::Interface& _interface) {
if (m_api == nullptr) { if (m_api == null) {
ATA_ERROR("Current Master API is nullptr ..."); ATA_ERROR("Current Master API is null ...");
return false; return false;
} }
if (_interface.m_api == nullptr) { if (_interface.m_api == null) {
ATA_ERROR("Current Slave API is nullptr ..."); ATA_ERROR("Current Slave API is null ...");
return false; return false;
} }
if (m_api->getCurrentApi() != _interface.m_api->getCurrentApi()) { if (m_api->getCurrentApi() != _interface.m_api->getCurrentApi()) {

View File

@ -6,8 +6,9 @@
*/ */
#pragma once #pragma once
#include <string> #include <etk/String.hpp>
#include <vector> #include <etk/Vector.hpp>
#include <etk/Pair.hpp>
#include <audio/orchestra/base.hpp> #include <audio/orchestra/base.hpp>
#include <audio/orchestra/CallbackInfo.hpp> #include <audio/orchestra/CallbackInfo.hpp>
#include <audio/orchestra/Api.hpp> #include <audio/orchestra/Api.hpp>
@ -26,12 +27,12 @@ namespace audio {
*/ */
class Interface { class Interface {
protected: protected:
std::vector<std::pair<std::string, ememory::SharedPtr<Api> (*)()> > m_apiAvaillable; etk::Vector<etk::Pair<etk::String, ememory::SharedPtr<Api> (*)()> > m_apiAvaillable;
protected: protected:
ememory::SharedPtr<audio::orchestra::Api> m_api; ememory::SharedPtr<audio::orchestra::Api> m_api;
public: public:
void setName(const std::string& _name) { void setName(const etk::String& _name) {
if (m_api == nullptr) { if (m_api == null) {
return; return;
} }
m_api->setName(_name); m_api->setName(_name);
@ -40,13 +41,13 @@ namespace audio {
* @brief Get the list of all availlable API in the system. * @brief Get the list of all availlable API in the system.
* @return the list of all APIs * @return the list of all APIs
*/ */
std::vector<std::string> getListApi(); etk::Vector<etk::String> getListApi();
/** /**
* @brief Add an interface of the Possible List. * @brief Add an interface of the Possible List.
* @param[in] _api Type of the interface. * @param[in] _api Type of the interface.
* @param[in] _callbackCreate API creation callback. * @param[in] _callbackCreate API creation callback.
*/ */
void addInterface(const std::string& _api, ememory::SharedPtr<Api> (*_callbackCreate)()); void addInterface(const etk::String& _api, ememory::SharedPtr<Api> (*_callbackCreate)());
/** /**
* @brief The class constructor. * @brief The class constructor.
* @note the creating of the basic instance is done by Instanciate * @note the creating of the basic instance is done by Instanciate
@ -66,12 +67,12 @@ namespace audio {
/** /**
* @brief Create an interface instance * @brief Create an interface instance
*/ */
enum audio::orchestra::error instanciate(const std::string& _api = audio::orchestra::typeUndefined); enum audio::orchestra::error instanciate(const etk::String& _api = audio::orchestra::typeUndefined);
/** /**
* @return the audio API specifier for the current instance of airtaudio. * @return the audio API specifier for the current instance of airtaudio.
*/ */
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
if (m_api == nullptr) { if (m_api == null) {
return audio::orchestra::typeUndefined; return audio::orchestra::typeUndefined;
} }
return m_api->getCurrentApi(); return m_api->getCurrentApi();
@ -84,7 +85,7 @@ namespace audio {
* a system error occurs during processing, a warning will be issued. * a system error occurs during processing, a warning will be issued.
*/ */
uint32_t getDeviceCount() { uint32_t getDeviceCount() {
if (m_api == nullptr) { if (m_api == null) {
return 0; return 0;
} }
return m_api->getDeviceCount(); return m_api->getDeviceCount();
@ -101,13 +102,13 @@ namespace audio {
* @return An audio::orchestra::DeviceInfo structure for a specified device number. * @return An audio::orchestra::DeviceInfo structure for a specified device number.
*/ */
audio::orchestra::DeviceInfo getDeviceInfo(uint32_t _device) { audio::orchestra::DeviceInfo getDeviceInfo(uint32_t _device) {
if (m_api == nullptr) { if (m_api == null) {
return audio::orchestra::DeviceInfo(); return audio::orchestra::DeviceInfo();
} }
return m_api->getDeviceInfo(_device); return m_api->getDeviceInfo(_device);
} }
audio::orchestra::DeviceInfo getDeviceInfo(const std::string& _deviceName) { audio::orchestra::DeviceInfo getDeviceInfo(const etk::String& _deviceName) {
if (m_api == nullptr) { if (m_api == null) {
return audio::orchestra::DeviceInfo(); return audio::orchestra::DeviceInfo();
} }
audio::orchestra::DeviceInfo info; audio::orchestra::DeviceInfo info;
@ -124,7 +125,7 @@ namespace audio {
* before attempting to open a stream. * before attempting to open a stream.
*/ */
uint32_t getDefaultOutputDevice() { uint32_t getDefaultOutputDevice() {
if (m_api == nullptr) { if (m_api == null) {
return 0; return 0;
} }
return m_api->getDefaultOutputDevice(); return m_api->getDefaultOutputDevice();
@ -139,7 +140,7 @@ namespace audio {
* before attempting to open a stream. * before attempting to open a stream.
*/ */
uint32_t getDefaultInputDevice() { uint32_t getDefaultInputDevice() {
if (m_api == nullptr) { if (m_api == null) {
return 0; return 0;
} }
return m_api->getDefaultInputDevice(); return m_api->getDefaultInputDevice();
@ -154,12 +155,12 @@ namespace audio {
* @param _outputParameters Specifies output stream parameters to use * @param _outputParameters Specifies output stream parameters to use
* when opening a stream, including a device ID, number of channels, * when opening a stream, including a device ID, number of channels,
* and starting channel number. For input-only streams, this * and starting channel number. For input-only streams, this
* argument should be nullptr. The device ID is an index value between * argument should be null. The device ID is an index value between
* 0 and getDeviceCount() - 1. * 0 and getDeviceCount() - 1.
* @param _inputParameters Specifies input stream parameters to use * @param _inputParameters Specifies input stream parameters to use
* when opening a stream, including a device ID, number of channels, * when opening a stream, including a device ID, number of channels,
* and starting channel number. For output-only streams, this * and starting channel number. For output-only streams, this
* argument should be nullptr. The device ID is an index value between * argument should be null. The device ID is an index value between
* 0 and getDeviceCount() - 1. * 0 and getDeviceCount() - 1.
* @param _format An audio::format specifying the desired sample data format. * @param _format An audio::format specifying the desired sample data format.
* @param _sampleRate The desired sample rate (sample frames per second). * @param _sampleRate The desired sample rate (sample frames per second).
@ -183,12 +184,12 @@ namespace audio {
* when an error has occured. * when an error has occured.
*/ */
enum audio::orchestra::error openStream(audio::orchestra::StreamParameters *_outputParameters, enum audio::orchestra::error openStream(audio::orchestra::StreamParameters *_outputParameters,
audio::orchestra::StreamParameters *_inputParameters, audio::orchestra::StreamParameters *_inputParameters,
enum audio::format _format, enum audio::format _format,
uint32_t _sampleRate, uint32_t _sampleRate,
uint32_t* _bufferFrames, uint32_t* _bufferFrames,
audio::orchestra::AirTAudioCallback _callback, audio::orchestra::AirTAudioCallback _callback,
const audio::orchestra::StreamOptions& _options = audio::orchestra::StreamOptions()); const audio::orchestra::StreamOptions& _options = audio::orchestra::StreamOptions());
/** /**
* @brief A function that closes a stream and frees any associated stream memory. * @brief A function that closes a stream and frees any associated stream memory.
@ -197,7 +198,7 @@ namespace audio {
* returns (no exception is thrown). * returns (no exception is thrown).
*/ */
enum audio::orchestra::error closeStream() { enum audio::orchestra::error closeStream() {
if (m_api == nullptr) { if (m_api == null) {
return audio::orchestra::error_inputNull; return audio::orchestra::error_inputNull;
} }
return m_api->closeStream(); return m_api->closeStream();
@ -211,7 +212,7 @@ namespace audio {
* running. * running.
*/ */
enum audio::orchestra::error startStream() { enum audio::orchestra::error startStream() {
if (m_api == nullptr) { if (m_api == null) {
return audio::orchestra::error_inputNull; return audio::orchestra::error_inputNull;
} }
return m_api->startStream(); return m_api->startStream();
@ -225,7 +226,7 @@ namespace audio {
* stopped. * stopped.
*/ */
enum audio::orchestra::error stopStream() { enum audio::orchestra::error stopStream() {
if (m_api == nullptr) { if (m_api == null) {
return audio::orchestra::error_inputNull; return audio::orchestra::error_inputNull;
} }
return m_api->stopStream(); return m_api->stopStream();
@ -238,7 +239,7 @@ namespace audio {
* stopped. * stopped.
*/ */
enum audio::orchestra::error abortStream() { enum audio::orchestra::error abortStream() {
if (m_api == nullptr) { if (m_api == null) {
return audio::orchestra::error_inputNull; return audio::orchestra::error_inputNull;
} }
return m_api->abortStream(); return m_api->abortStream();
@ -247,7 +248,7 @@ namespace audio {
* @return true if a stream is open and false if not. * @return true if a stream is open and false if not.
*/ */
bool isStreamOpen() const { bool isStreamOpen() const {
if (m_api == nullptr) { if (m_api == null) {
return false; return false;
} }
return m_api->isStreamOpen(); return m_api->isStreamOpen();
@ -256,7 +257,7 @@ namespace audio {
* @return true if the stream is running and false if it is stopped or not open. * @return true if the stream is running and false if it is stopped or not open.
*/ */
bool isStreamRunning() const { bool isStreamRunning() const {
if (m_api == nullptr) { if (m_api == null) {
return false; return false;
} }
return m_api->isStreamRunning(); return m_api->isStreamRunning();
@ -266,7 +267,7 @@ namespace audio {
* @return the number of elapsed seconds since the stream was started. * @return the number of elapsed seconds since the stream was started.
*/ */
audio::Time getStreamTime() { audio::Time getStreamTime() {
if (m_api == nullptr) { if (m_api == null) {
return audio::Time(); return audio::Time();
} }
return m_api->getStreamTime(); return m_api->getStreamTime();
@ -281,7 +282,7 @@ namespace audio {
* @return The internal stream latency in sample frames. * @return The internal stream latency in sample frames.
*/ */
long getStreamLatency() { long getStreamLatency() {
if (m_api == nullptr) { if (m_api == null) {
return 0; return 0;
} }
return m_api->getStreamLatency(); return m_api->getStreamLatency();
@ -293,14 +294,14 @@ namespace audio {
* @return Returns actual sample rate in use by the stream. * @return Returns actual sample rate in use by the stream.
*/ */
uint32_t getStreamSampleRate() { uint32_t getStreamSampleRate() {
if (m_api == nullptr) { if (m_api == null) {
return 0; return 0;
} }
return m_api->getStreamSampleRate(); return m_api->getStreamSampleRate();
} }
bool isMasterOf(audio::orchestra::Interface& _interface); bool isMasterOf(audio::orchestra::Interface& _interface);
protected: protected:
void openApi(const std::string& _api); void openApi(const etk::String& _api);
}; };
} }
} }

View File

@ -15,13 +15,13 @@ static const char* listValue[] = {
"soft" "soft"
}; };
std::ostream& audio::orchestra::operator <<(std::ostream& _os, enum audio::orchestra::timestampMode _obj) { etk::Stream& audio::orchestra::operator <<(etk::Stream& _os, enum audio::orchestra::timestampMode _obj) {
_os << listValue[_obj]; _os << listValue[_obj];
return _os; return _os;
} }
namespace etk { namespace etk {
template <> bool from_string<enum audio::orchestra::timestampMode>(enum audio::orchestra::timestampMode& _variableRet, const std::string& _value) { template <> bool from_string<enum audio::orchestra::timestampMode>(enum audio::orchestra::timestampMode& _variableRet, const etk::String& _value) {
if (_value == "hardware") { if (_value == "hardware") {
_variableRet = audio::orchestra::timestampMode_Hardware; _variableRet = audio::orchestra::timestampMode_Hardware;
return true; return true;
@ -37,7 +37,7 @@ namespace etk {
return false; return false;
} }
template <enum audio::orchestra::timestampMode> std::string to_string(const enum audio::orchestra::timestampMode& _variable) { template <enum audio::orchestra::timestampMode> etk::String toString(const enum audio::orchestra::timestampMode& _variable) {
return listValue[_variable]; return listValue[_variable];
} }
} }

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include <audio/orchestra/Flags.hpp> #include <audio/orchestra/Flags.hpp>
#include <etk/String.hpp>
namespace audio { namespace audio {
namespace orchestra { namespace orchestra {
@ -15,13 +16,13 @@ namespace audio {
timestampMode_trigered, //!< get harware triger time stamp and increment with duration timestampMode_trigered, //!< get harware triger time stamp and increment with duration
timestampMode_soft, //!< Simulate all timestamp. timestampMode_soft, //!< Simulate all timestamp.
}; };
std::ostream& operator <<(std::ostream& _os, enum audio::orchestra::timestampMode _obj); etk::Stream& operator <<(etk::Stream& _os, enum audio::orchestra::timestampMode _obj);
class StreamOptions { class StreamOptions {
public: public:
audio::orchestra::Flags flags; //!< A bit-mask of stream flags audio::orchestra::Flags flags; //!< A bit-mask of stream flags
uint32_t numberOfBuffers; //!< Number of stream buffers. uint32_t numberOfBuffers; //!< Number of stream buffers.
std::string streamName; //!< A stream name (currently used only in Jack). etk::String streamName; //!< A stream name (currently used only in Jack).
enum timestampMode mode; //!< mode of timestamping data... enum timestampMode mode; //!< mode of timestamping data...
// Default constructor. // Default constructor.
StreamOptions() : StreamOptions() :

View File

@ -14,7 +14,7 @@ namespace audio {
class StreamParameters { class StreamParameters {
public: public:
int32_t deviceId; //!< Device index (-1 to getDeviceCount() - 1). int32_t deviceId; //!< Device index (-1 to getDeviceCount() - 1).
std::string deviceName; //!< name of the device (if deviceId==-1 this must not be == "", and the oposite ...) etk::String deviceName; //!< name of the device (if deviceId==-1 this must not be == "", and the oposite ...)
uint32_t nChannels; //!< Number of channels. uint32_t nChannels; //!< Number of channels.
uint32_t firstChannel; //!< First channel index on device (default = 0). uint32_t firstChannel; //!< First channel index on device (default = 0).
// Default constructor. // Default constructor.

View File

@ -14,22 +14,22 @@
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <etk/stdTools.hpp> #include <etk/stdTools.hpp>
#include <ethread/tools.hpp> #include <ethread/tools.hpp>
#include <climits>
#include <audio/orchestra/api/Alsa.hpp> #include <audio/orchestra/api/Alsa.hpp>
extern "C" { extern "C" {
#include <sched.h> #include <sched.h>
#include <getopt.h> #include <getopt.h>
#include <sys/time.h> #include <sys/time.h>
#include <poll.h> #include <poll.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>
} }
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Alsa::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Alsa::create() {
return ememory::SharedPtr<audio::orchestra::api::Alsa>(new audio::orchestra::api::Alsa()); return ememory::SharedPtr<audio::orchestra::api::Alsa>(ETK_NEW(audio::orchestra::api::Alsa));
} }
namespace audio { namespace audio {
@ -39,17 +39,17 @@ namespace audio {
public: public:
snd_pcm_t *handle; snd_pcm_t *handle;
bool xrun[2]; bool xrun[2];
std::condition_variable runnable_cv; ethread::Semaphore m_semaphore;
bool runnable; bool runnable;
std::thread* thread; ethread::Thread* thread;
bool threadRunning; bool threadRunning;
bool mmapInterface; //!< enable or disable mmap mode... bool mmapInterface; //!< enable or disable mmap mode...
enum timestampMode timeMode; //!< the timestamp of the flow came from the harware. enum timestampMode timeMode; //!< the timestamp of the flow came from the harware.
std::vector<snd_pcm_channel_area_t> areas; etk::Vector<snd_pcm_channel_area_t> areas;
AlsaPrivate() : AlsaPrivate() :
handle(nullptr), handle(null),
runnable(false), runnable(false),
thread(nullptr), thread(null),
threadRunning(false), threadRunning(false),
mmapInterface(false), mmapInterface(false),
timeMode(timestampMode_soft) { timeMode(timestampMode_soft) {
@ -112,7 +112,7 @@ nextcard:
return nDevices; return nDevices;
} }
bool audio::orchestra::api::Alsa::getNamedDeviceInfoLocal(const std::string& _deviceName, audio::orchestra::DeviceInfo& _info, int32_t _cardId, int32_t _subdevice, int32_t _localDeviceId, bool _input) { bool audio::orchestra::api::Alsa::getNamedDeviceInfoLocal(const etk::String& _deviceName, audio::orchestra::DeviceInfo& _info, int32_t _cardId, int32_t _subdevice, int32_t _localDeviceId, bool _input) {
int32_t result; int32_t result;
snd_ctl_t *chandle; snd_ctl_t *chandle;
int32_t openMode = SND_PCM_ASYNC; int32_t openMode = SND_PCM_ASYNC;
@ -130,7 +130,7 @@ bool audio::orchestra::api::Alsa::getNamedDeviceInfoLocal(const std::string& _de
stream = SND_PCM_STREAM_PLAYBACK; stream = SND_PCM_STREAM_PLAYBACK;
} }
snd_pcm_info_set_stream(pcminfo, stream); snd_pcm_info_set_stream(pcminfo, stream);
std::vector<std::string> listElement = etk::split(_deviceName, ','); etk::Vector<etk::String> listElement = etk::split(_deviceName, ',');
if (listElement.size() == 0) { if (listElement.size() == 0) {
ATA_ERROR("can not get control interface = '" << _deviceName << "' Can not plit at ',' ..."); ATA_ERROR("can not get control interface = '" << _deviceName << "' Can not plit at ',' ...");
return false; return false;
@ -190,15 +190,13 @@ bool audio::orchestra::api::Alsa::getNamedDeviceInfoLocal(const std::string& _de
} }
ATA_DEBUG("Input channel = " << value); ATA_DEBUG("Input channel = " << value);
for (int32_t iii=0; iii<value; ++iii) { for (int32_t iii=0; iii<value; ++iii) {
_info.channels.push_back(audio::channel_unknow); _info.channels.pushBack(audio::channel_unknow);
} }
// Test our discrete set of sample rate values. // Test our discrete set of sample rate values.
_info.sampleRates.clear(); _info.sampleRates.clear();
for (std::vector<uint32_t>::const_iterator it(audio::orchestra::genericSampleRate().begin()); for (auto &it: audio::orchestra::genericSampleRate()) {
it != audio::orchestra::genericSampleRate().end(); if (snd_pcm_hw_params_test_rate(phandle, params, it, 0) == 0) {
++it ) { _info.sampleRates.pushBack(it);
if (snd_pcm_hw_params_test_rate(phandle, params, *it, 0) == 0) {
_info.sampleRates.push_back(*it);
} }
} }
if (_info.sampleRates.size() == 0) { if (_info.sampleRates.size() == 0) {
@ -211,27 +209,27 @@ bool audio::orchestra::api::Alsa::getNamedDeviceInfoLocal(const std::string& _de
_info.nativeFormats.clear(); _info.nativeFormats.clear();
format = SND_PCM_FORMAT_S8; format = SND_PCM_FORMAT_S8;
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) { if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
_info.nativeFormats.push_back(audio::format_int8); _info.nativeFormats.pushBack(audio::format_int8);
} }
format = SND_PCM_FORMAT_S16; format = SND_PCM_FORMAT_S16;
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) { if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
_info.nativeFormats.push_back(audio::format_int16); _info.nativeFormats.pushBack(audio::format_int16);
} }
format = SND_PCM_FORMAT_S24; format = SND_PCM_FORMAT_S24;
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) { if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
_info.nativeFormats.push_back(audio::format_int24); _info.nativeFormats.pushBack(audio::format_int24);
} }
format = SND_PCM_FORMAT_S32; format = SND_PCM_FORMAT_S32;
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) { if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
_info.nativeFormats.push_back(audio::format_int32); _info.nativeFormats.pushBack(audio::format_int32);
} }
format = SND_PCM_FORMAT_FLOAT; format = SND_PCM_FORMAT_FLOAT;
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) { if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
_info.nativeFormats.push_back(audio::format_float); _info.nativeFormats.pushBack(audio::format_float);
} }
format = SND_PCM_FORMAT_FLOAT64; format = SND_PCM_FORMAT_FLOAT64;
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) { if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
_info.nativeFormats.push_back(audio::format_double); _info.nativeFormats.pushBack(audio::format_double);
} }
// Check that we have at least one supported format // Check that we have at least one supported format
if (_info.nativeFormats.size() == 0) { if (_info.nativeFormats.size() == 0) {
@ -406,7 +404,7 @@ foundDevice:
return openName(name, _mode, _channels, _firstChannel, _sampleRate, _format, _bufferSize, _options); return openName(name, _mode, _channels, _firstChannel, _sampleRate, _format, _bufferSize, _options);
} }
bool audio::orchestra::api::Alsa::openName(const std::string& _deviceName, bool audio::orchestra::api::Alsa::openName(const etk::String& _deviceName,
audio::orchestra::mode _mode, audio::orchestra::mode _mode,
uint32_t _channels, uint32_t _channels,
uint32_t _firstChannel, uint32_t _firstChannel,
@ -676,7 +674,7 @@ bool audio::orchestra::api::Alsa::openName(const std::string& _deviceName,
} }
snd_pcm_uframes_t val; snd_pcm_uframes_t val;
// Set the software configuration to fill buffers with zeros and prevent device stopping on xruns. // Set the software configuration to fill buffers with zeros and prevent device stopping on xruns.
snd_pcm_sw_params_t *swParams = nullptr; snd_pcm_sw_params_t *swParams = null;
snd_pcm_sw_params_alloca(&swParams); snd_pcm_sw_params_alloca(&swParams);
snd_pcm_sw_params_current(m_private->handle, swParams); snd_pcm_sw_params_current(m_private->handle, swParams);
#if 0 #if 0
@ -783,10 +781,10 @@ bool audio::orchestra::api::Alsa::openName(const std::string& _deviceName,
bufferBytes *= *_bufferSize; bufferBytes *= *_bufferSize;
if (m_deviceBuffer) { if (m_deviceBuffer) {
free(m_deviceBuffer); free(m_deviceBuffer);
m_deviceBuffer = nullptr; m_deviceBuffer = null;
} }
m_deviceBuffer = (char *) calloc(bufferBytes, 1); m_deviceBuffer = (char *) calloc(bufferBytes, 1);
if (m_deviceBuffer == nullptr) { if (m_deviceBuffer == null) {
ATA_ERROR("error allocating device buffer memory."); ATA_ERROR("error allocating device buffer memory.");
goto error; goto error;
} }
@ -803,8 +801,8 @@ bool audio::orchestra::api::Alsa::openName(const std::string& _deviceName,
// Setup callback thread. // Setup callback thread.
m_private->threadRunning = true; m_private->threadRunning = true;
ATA_INFO("create thread ..."); ATA_INFO("create thread ...");
m_private->thread = new std::thread(&audio::orchestra::api::Alsa::alsaCallbackEvent, this); m_private->thread = ETK_NEW(ethread::Thread, [=]() {callbackEvent();});
if (m_private->thread == nullptr) { if (m_private->thread == null) {
m_private->threadRunning = false; m_private->threadRunning = false;
ATA_ERROR("creating callback thread!"); ATA_ERROR("creating callback thread!");
goto error; goto error;
@ -814,7 +812,7 @@ bool audio::orchestra::api::Alsa::openName(const std::string& _deviceName,
error: error:
if (m_private->handle) { if (m_private->handle) {
snd_pcm_close(m_private->handle); snd_pcm_close(m_private->handle);
m_private->handle = nullptr; m_private->handle = null;
} }
for (int32_t iii=0; iii<2; ++iii) { for (int32_t iii=0; iii<2; ++iii) {
m_userBuffer[iii].clear(); m_userBuffer[iii].clear();
@ -836,12 +834,12 @@ enum audio::orchestra::error audio::orchestra::api::Alsa::closeStream() {
m_mutex.lock(); m_mutex.lock();
if (m_state == audio::orchestra::state::stopped) { if (m_state == audio::orchestra::state::stopped) {
m_private->runnable = true; m_private->runnable = true;
m_private->runnable_cv.notify_one(); m_private->m_semaphore.post();
} }
m_mutex.unlock(); m_mutex.unLock();
if (m_private->thread != nullptr) { if (m_private->thread != null) {
m_private->thread->join(); m_private->thread->join();
m_private->thread = nullptr; m_private->thread = null;
} }
if (m_state == audio::orchestra::state::running) { if (m_state == audio::orchestra::state::running) {
m_state = audio::orchestra::state::stopped; m_state = audio::orchestra::state::stopped;
@ -850,7 +848,7 @@ enum audio::orchestra::error audio::orchestra::api::Alsa::closeStream() {
// close all stream : // close all stream :
if (m_private->handle) { if (m_private->handle) {
snd_pcm_close(m_private->handle); snd_pcm_close(m_private->handle);
m_private->handle = nullptr; m_private->handle = null;
} }
for (int32_t iii=0; iii<2; ++iii) { for (int32_t iii=0; iii<2; ++iii) {
m_userBuffer[iii].clear(); m_userBuffer[iii].clear();
@ -865,23 +863,29 @@ enum audio::orchestra::error audio::orchestra::api::Alsa::closeStream() {
} }
enum audio::orchestra::error audio::orchestra::api::Alsa::startStream() { enum audio::orchestra::error audio::orchestra::api::Alsa::startStream() {
ATA_DEBUG("Start stream (DEGIN)");
// TODO : Check return ... // TODO : Check return ...
//audio::orchestra::Api::startStream(); //audio::orchestra::Api::startStream();
// This method calls snd_pcm_prepare if the device isn't already in that state. // This method calls snd_pcm_prepare if the device isn't already in that state.
if (verifyStream() != audio::orchestra::error_none) { if (verifyStream() != audio::orchestra::error_none) {
ATA_WARNING("the stream not prepared!");
return audio::orchestra::error_fail; return audio::orchestra::error_fail;
} }
if (m_state == audio::orchestra::state::running) { if (m_state == audio::orchestra::state::running) {
ATA_ERROR("the stream is already running!"); ATA_ERROR("the stream is already running!");
return audio::orchestra::error_warning; return audio::orchestra::error_warning;
} }
std::unique_lock<std::mutex> lck(m_mutex); ATA_DEBUG("Lock");
ethread::UniqueLock lck(m_mutex);
ATA_DEBUG("Lock (done)");
int32_t result = 0; int32_t result = 0;
snd_pcm_state_t state; snd_pcm_state_t state;
if (m_private->handle == nullptr) { if (m_private->handle == null) {
ATA_ERROR("send nullptr to alsa ..."); ATA_ERROR("send null to alsa ...");
} }
ATA_DEBUG("snd_pcm_state");
state = snd_pcm_state(m_private->handle); state = snd_pcm_state(m_private->handle);
ATA_DEBUG("snd_pcm_state (done)");
if (state != SND_PCM_STATE_PREPARED) { if (state != SND_PCM_STATE_PREPARED) {
ATA_ERROR("prepare stream"); ATA_ERROR("prepare stream");
result = snd_pcm_prepare(m_private->handle); result = snd_pcm_prepare(m_private->handle);
@ -893,10 +897,12 @@ enum audio::orchestra::error audio::orchestra::api::Alsa::startStream() {
m_state = audio::orchestra::state::running; m_state = audio::orchestra::state::running;
unlock: unlock:
m_private->runnable = true; m_private->runnable = true;
m_private->runnable_cv.notify_one(); m_private->m_semaphore.post();
if (result >= 0) { if (result >= 0) {
ATA_DEBUG("Start stream (END2)");
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
ATA_DEBUG("Start stream (END)");
return audio::orchestra::error_systemError; return audio::orchestra::error_systemError;
} }
@ -909,7 +915,7 @@ enum audio::orchestra::error audio::orchestra::api::Alsa::stopStream() {
return audio::orchestra::error_warning; return audio::orchestra::error_warning;
} }
m_state = audio::orchestra::state::stopped; m_state = audio::orchestra::state::stopped;
std::unique_lock<std::mutex> lck(m_mutex); ethread::UniqueLock lck(m_mutex);
int32_t result = 0; int32_t result = 0;
if (m_mode == audio::orchestra::mode_output) { if (m_mode == audio::orchestra::mode_output) {
result = snd_pcm_drain(m_private->handle); result = snd_pcm_drain(m_private->handle);
@ -936,7 +942,7 @@ enum audio::orchestra::error audio::orchestra::api::Alsa::abortStream() {
return audio::orchestra::error_warning; return audio::orchestra::error_warning;
} }
m_state = audio::orchestra::state::stopped; m_state = audio::orchestra::state::stopped;
std::unique_lock<std::mutex> lck(m_mutex); ethread::UniqueLock lck(m_mutex);
int32_t result = 0; int32_t result = 0;
result = snd_pcm_drop(m_private->handle); result = snd_pcm_drop(m_private->handle);
if (result < 0) { if (result < 0) {
@ -950,12 +956,6 @@ unlock:
return audio::orchestra::error_systemError; return audio::orchestra::error_systemError;
} }
void audio::orchestra::api::Alsa::alsaCallbackEvent(void *_userData) {
audio::orchestra::api::Alsa* myClass = reinterpret_cast<audio::orchestra::api::Alsa*>(_userData);
myClass->callbackEvent();
}
/** /**
* @briefTransfer method - write and wait for room in buffer using poll * @briefTransfer method - write and wait for room in buffer using poll
*/ */
@ -979,9 +979,8 @@ static int32_t wait_for_poll(snd_pcm_t* _handle, struct pollfd* _ufds, unsigned
void audio::orchestra::api::Alsa::callbackEvent() { void audio::orchestra::api::Alsa::callbackEvent() {
// Lock while the system is not started ... // Lock while the system is not started ...
if (m_state == audio::orchestra::state::stopped) { if (m_state == audio::orchestra::state::stopped) {
std::unique_lock<std::mutex> lck(m_mutex);
while (!m_private->runnable) { while (!m_private->runnable) {
m_private->runnable_cv.wait(lck); m_private->m_semaphore.wait();
} }
if (m_state != audio::orchestra::state::running) { if (m_state != audio::orchestra::state::running) {
return; return;
@ -989,7 +988,7 @@ void audio::orchestra::api::Alsa::callbackEvent() {
} }
ethread::setName("Alsa IO-" + m_name); ethread::setName("Alsa IO-" + m_name);
//Wait data with poll //Wait data with poll
std::vector<struct pollfd> ufds; etk::Vector<struct pollfd> ufds;
signed short *ptr; signed short *ptr;
int32_t err, count, cptr, init; int32_t err, count, cptr, init;
count = snd_pcm_poll_descriptors_count(m_private->handle); count = snd_pcm_poll_descriptors_count(m_private->handle);
@ -1032,7 +1031,7 @@ void audio::orchestra::api::Alsa::callbackEvent() {
audio::Time audio::orchestra::api::Alsa::getStreamTime() { audio::Time audio::orchestra::api::Alsa::getStreamTime() {
//ATA_DEBUG("mode : " << m_private->timeMode); //ATA_DEBUG("mode : " << m_private->timeMode);
if (m_private->timeMode == timestampMode_Hardware) { if (m_private->timeMode == timestampMode_Hardware) {
snd_pcm_status_t *status = nullptr; snd_pcm_status_t *status = null;
snd_pcm_status_alloca(&status); snd_pcm_status_alloca(&status);
// get harware timestamp all the time: // get harware timestamp all the time:
snd_pcm_status(m_private->handle, status); snd_pcm_status(m_private->handle, status);
@ -1055,7 +1054,7 @@ audio::Time audio::orchestra::api::Alsa::getStreamTime() {
ATA_VERBOSE("snd_pcm_status_get_htstamp : " << m_startTime); ATA_VERBOSE("snd_pcm_status_get_htstamp : " << m_startTime);
snd_pcm_sframes_t delay = snd_pcm_status_get_delay(status); snd_pcm_sframes_t delay = snd_pcm_status_get_delay(status);
audio::Duration timeDelay = audio::Duration(0, delay*1000000000LL/int64_t(m_sampleRate)); audio::Duration timeDelay = audio::Duration(0, delay*1000000000LL/int64_t(m_sampleRate));
ATA_VERBOSE("delay : " << timeDelay.count() << " ns"); ATA_VERBOSE("delay : " << timeDelay);
//return m_startTime + m_duration; //return m_startTime + m_duration;
if (m_mode == audio::orchestra::mode_output) { if (m_mode == audio::orchestra::mode_output) {
// output // output
@ -1067,7 +1066,7 @@ audio::Time audio::orchestra::api::Alsa::getStreamTime() {
return m_startTime; return m_startTime;
} else if (m_private->timeMode == timestampMode_trigered) { } else if (m_private->timeMode == timestampMode_trigered) {
if (m_startTime == audio::Time()) { if (m_startTime == audio::Time()) {
snd_pcm_status_t *status = nullptr; snd_pcm_status_t *status = null;
snd_pcm_status_alloca(&status); snd_pcm_status_alloca(&status);
// get harware timestamp all the time: // get harware timestamp all the time:
snd_pcm_status(m_private->handle, status); snd_pcm_status(m_private->handle, status);
@ -1106,9 +1105,9 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleRead() {
} }
int32_t doStopStream = 0; int32_t doStopStream = 0;
audio::Time streamTime; audio::Time streamTime;
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if (m_private->xrun[0] == true) { if (m_private->xrun[0] == true) {
status.push_back(audio::orchestra::status::underflow); status.pushBack(audio::orchestra::status::underflow);
m_private->xrun[0] = false; m_private->xrun[0] = false;
} }
int32_t result; int32_t result;
@ -1121,7 +1120,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleRead() {
// !!! goto unlock; // !!! goto unlock;
} }
std::unique_lock<std::mutex> lck(m_mutex); ethread::UniqueLock lck(m_mutex);
// Setup parameters. // Setup parameters.
if (m_doConvertBuffer[1]) { if (m_doConvertBuffer[1]) {
buffer = m_deviceBuffer; buffer = m_deviceBuffer;
@ -1167,7 +1166,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleRead() {
} }
} else { } else {
ATA_ERROR("audio read error, " << snd_strerror(result) << "."); ATA_ERROR("audio read error, " << snd_strerror(result) << ".");
std::this_thread::sleep_for(std::chrono::milliseconds(10)); ethread::sleepMilliSeconds((10));
} }
// TODO : Notify application ... audio::orchestra::error_warning; // TODO : Notify application ... audio::orchestra::error_warning;
goto noInput; goto noInput;
@ -1193,7 +1192,7 @@ noInput:
audio::Time startCall = audio::Time::now(); audio::Time startCall = audio::Time::now();
doStopStream = m_callback(&m_userBuffer[1][0], doStopStream = m_callback(&m_userBuffer[1][0],
streamTime,// - audio::Duration(m_latency[1]*1000000000LL/int64_t(m_sampleRate)), streamTime,// - audio::Duration(m_latency[1]*1000000000LL/int64_t(m_sampleRate)),
nullptr, null,
audio::Time(), audio::Time(),
m_bufferSize, m_bufferSize,
status); status);
@ -1201,7 +1200,7 @@ noInput:
audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate)); audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate));
audio::Duration timeProcess = stopCall - startCall; audio::Duration timeProcess = stopCall - startCall;
if (timeDelay <= timeProcess) { if (timeDelay <= timeProcess) {
ATA_ERROR("SOFT XRUN ... : (bufferTime) " << timeDelay.count() << " < " << timeProcess.count() << " (process time) ns"); ATA_ERROR("SOFT XRUN ... : (bufferTime) " << timeDelay << " < " << timeProcess << " (process time)");
} }
} }
if (doStopStream == 2) { if (doStopStream == 2) {
@ -1223,9 +1222,9 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleWrite() {
} }
int32_t doStopStream = 0; int32_t doStopStream = 0;
audio::Time streamTime; audio::Time streamTime;
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if (m_private->xrun[1] == true) { if (m_private->xrun[1] == true) {
status.push_back(audio::orchestra::status::overflow); status.pushBack(audio::orchestra::status::overflow);
m_private->xrun[1] = false; m_private->xrun[1] = false;
} }
int32_t result; int32_t result;
@ -1241,7 +1240,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleWrite() {
streamTime = getStreamTime(); streamTime = getStreamTime();
{ {
audio::Time startCall = audio::Time::now(); audio::Time startCall = audio::Time::now();
doStopStream = m_callback(nullptr, doStopStream = m_callback(null,
audio::Time(), audio::Time(),
&m_userBuffer[0][0], &m_userBuffer[0][0],
streamTime,// + audio::Duration(m_latency[0]*1000000000LL/int64_t(m_sampleRate)), streamTime,// + audio::Duration(m_latency[0]*1000000000LL/int64_t(m_sampleRate)),
@ -1251,14 +1250,14 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleWrite() {
audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate)); audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate));
audio::Duration timeProcess = stopCall - startCall; audio::Duration timeProcess = stopCall - startCall;
if (timeDelay <= timeProcess) { if (timeDelay <= timeProcess) {
ATA_ERROR("SOFT XRUN ... : (bufferTime) " << timeDelay.count() << " < " << timeProcess.count() << " (process time) ns"); ATA_ERROR("SOFT XRUN ... : (bufferTime) " << timeDelay << " < " << timeProcess << " (process time)");
} }
} }
if (doStopStream == 2) { if (doStopStream == 2) {
abortStream(); abortStream();
return; return;
} }
std::unique_lock<std::mutex> lck(m_mutex); ethread::UniqueLock lck(m_mutex);
// Setup parameters and do buffer conversion if necessary. // Setup parameters and do buffer conversion if necessary.
if (m_doConvertBuffer[0]) { if (m_doConvertBuffer[0]) {
buffer = m_deviceBuffer; buffer = m_deviceBuffer;
@ -1325,9 +1324,9 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPWrite() {
} }
int32_t doStopStream = 0; int32_t doStopStream = 0;
audio::Time streamTime; audio::Time streamTime;
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if (m_private->xrun[1] == true) { if (m_private->xrun[1] == true) {
status.push_back(audio::orchestra::status::overflow); status.pushBack(audio::orchestra::status::overflow);
m_private->xrun[1] = false; m_private->xrun[1] = false;
} }
int32_t result; int32_t result;
@ -1347,7 +1346,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPWrite() {
streamTime = getStreamTime(); streamTime = getStreamTime();
{ {
audio::Time startCall = audio::Time::now(); audio::Time startCall = audio::Time::now();
doStopStream = m_callback(nullptr, doStopStream = m_callback(null,
audio::Time(), audio::Time(),
&m_userBuffer[0][0], &m_userBuffer[0][0],
streamTime,// + audio::Duration(m_latency[0]*1000000000LL/int64_t(m_sampleRate)), streamTime,// + audio::Duration(m_latency[0]*1000000000LL/int64_t(m_sampleRate)),
@ -1357,7 +1356,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPWrite() {
audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate)); audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate));
audio::Duration timeProcess = stopCall - startCall; audio::Duration timeProcess = stopCall - startCall;
if (timeDelay <= timeProcess) { if (timeDelay <= timeProcess) {
ATA_ERROR("SOFT XRUN ... : (bufferTime) " << timeDelay.count() << " < " << timeProcess.count() << " (process time) ns"); ATA_ERROR("SOFT XRUN ... : (bufferTime) " << timeDelay << " < " << timeProcess << " (process time)");
} }
} }
if (doStopStream == 2) { if (doStopStream == 2) {
@ -1365,7 +1364,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPWrite() {
return; return;
} }
{ {
std::unique_lock<std::mutex> lck(m_mutex); ethread::UniqueLock lck(m_mutex);
// Setup parameters and do buffer conversion if necessary. // Setup parameters and do buffer conversion if necessary.
if (m_doConvertBuffer[0]) { if (m_doConvertBuffer[0]) {
buffer = m_deviceBuffer; buffer = m_deviceBuffer;
@ -1397,7 +1396,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPWrite() {
// TODO: Understand why this does not work ... // TODO: Understand why this does not work ...
// Write samples to device in interleaved/non-interleaved format. // Write samples to device in interleaved/non-interleaved format.
if (m_deviceInterleaved[0]) { if (m_deviceInterleaved[0]) {
const snd_pcm_channel_area_t* myAreas = nullptr; const snd_pcm_channel_area_t* myAreas = null;
snd_pcm_uframes_t offset, frames; snd_pcm_uframes_t offset, frames;
frames = m_bufferSize; frames = m_bufferSize;
ATA_DEBUG("START"); ATA_DEBUG("START");
@ -1459,9 +1458,9 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPRead() {
} }
int32_t doStopStream = 0; int32_t doStopStream = 0;
audio::Time streamTime; audio::Time streamTime;
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if (m_private->xrun[0] == true) { if (m_private->xrun[0] == true) {
status.push_back(audio::orchestra::status::underflow); status.pushBack(audio::orchestra::status::underflow);
m_private->xrun[0] = false; m_private->xrun[0] = false;
} }
int32_t result; int32_t result;
@ -1474,7 +1473,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPRead() {
goto unlock; goto unlock;
} }
{ {
std::unique_lock<std::mutex> lck(m_mutex); ethread::UniqueLock lck(m_mutex);
// Setup parameters. // Setup parameters.
if (m_doConvertBuffer[1]) { if (m_doConvertBuffer[1]) {
buffer = m_deviceBuffer; buffer = m_deviceBuffer;
@ -1521,7 +1520,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPRead() {
} }
} else { } else {
ATA_ERROR("audio read error, " << snd_strerror(result) << "."); ATA_ERROR("audio read error, " << snd_strerror(result) << ".");
std::this_thread::sleep_for(std::chrono::milliseconds(10)); ethread::sleepMilliSeconds((10));
} }
// TODO : Notify application ... audio::orchestra::error_warning; // TODO : Notify application ... audio::orchestra::error_warning;
goto noInput; goto noInput;
@ -1549,7 +1548,7 @@ noInput:
audio::Time startCall = audio::Time::now(); audio::Time startCall = audio::Time::now();
doStopStream = m_callback(&m_userBuffer[1][0], doStopStream = m_callback(&m_userBuffer[1][0],
streamTime,// - audio::Duration(m_latency[1]*1000000000LL/int64_t(m_sampleRate)), streamTime,// - audio::Duration(m_latency[1]*1000000000LL/int64_t(m_sampleRate)),
nullptr, null,
audio::Time(), audio::Time(),
m_bufferSize, m_bufferSize,
status); status);
@ -1557,7 +1556,7 @@ noInput:
audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate)); audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate));
audio::Duration timeProcess = stopCall - startCall; audio::Duration timeProcess = stopCall - startCall;
if (timeDelay <= timeProcess) { if (timeDelay <= timeProcess) {
ATA_ERROR("SOFT XRUN ... : (bufferTime) " << timeDelay.count() << " < " << timeProcess.count() << " (process time) ns"); ATA_ERROR("SOFT XRUN ... : (bufferTime) " << timeDelay << " < " << timeProcess << " (process time) ns");
} }
} }
if (doStopStream == 2) { if (doStopStream == 2) {
@ -1574,7 +1573,7 @@ unlock:
bool audio::orchestra::api::Alsa::isMasterOf(ememory::SharedPtr<audio::orchestra::Api> _api) { bool audio::orchestra::api::Alsa::isMasterOf(ememory::SharedPtr<audio::orchestra::Api> _api) {
ememory::SharedPtr<audio::orchestra::api::Alsa> slave = ememory::dynamicPointerCast<audio::orchestra::api::Alsa>(_api); ememory::SharedPtr<audio::orchestra::api::Alsa> slave = ememory::dynamicPointerCast<audio::orchestra::api::Alsa>(_api);
if (slave == nullptr) { if (slave == null) {
ATA_ERROR("NULL ptr API (not ALSA ...)"); ATA_ERROR("NULL ptr API (not ALSA ...)");
return false; return false;
} }
@ -1586,11 +1585,11 @@ bool audio::orchestra::api::Alsa::isMasterOf(ememory::SharedPtr<audio::orchestra
ATA_ERROR("The SLAVE stream is already running! ==> can not synchronize ..."); ATA_ERROR("The SLAVE stream is already running! ==> can not synchronize ...");
return false; return false;
} }
snd_pcm_t * master = nullptr; snd_pcm_t * master = null;
if (m_private->handle != nullptr) { if (m_private->handle != null) {
master = m_private->handle; master = m_private->handle;
} }
if (master == nullptr) { if (master == null) {
ATA_ERROR("No ALSA handles ..."); ATA_ERROR("No ALSA handles ...");
return false; return false;
} }

View File

@ -18,19 +18,19 @@ namespace audio {
public: public:
Alsa(); Alsa();
virtual ~Alsa(); virtual ~Alsa();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typeAlsa; return audio::orchestra::typeAlsa;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();
private: private:
bool getNamedDeviceInfoLocal(const std::string& _deviceName, bool getNamedDeviceInfoLocal(const etk::String& _deviceName,
audio::orchestra::DeviceInfo& _info, audio::orchestra::DeviceInfo& _info,
int32_t _cardId=-1, // Alsa card ID int32_t _cardId=-1, // Alsa card ID
int32_t _subdevice=-1, // alsa subdevice ID int32_t _subdevice=-1, // alsa subdevice ID
int32_t _localDeviceId=-1,// local ID of device find int32_t _localDeviceId=-1,// local ID of device find
bool _input=false); bool _input=false);
public: public:
bool getNamedDeviceInfo(const std::string& _deviceName, audio::orchestra::DeviceInfo& _info) { bool getNamedDeviceInfo(const etk::String& _deviceName, audio::orchestra::DeviceInfo& _info) {
return getNamedDeviceInfoLocal(_deviceName, _info); return getNamedDeviceInfoLocal(_deviceName, _info);
} }
audio::orchestra::DeviceInfo getDeviceInfo(uint32_t _device); audio::orchestra::DeviceInfo getDeviceInfo(uint32_t _device);
@ -47,11 +47,9 @@ namespace audio {
void callbackEventOneCycleWrite(); void callbackEventOneCycleWrite();
void callbackEventOneCycleMMAPRead(); void callbackEventOneCycleMMAPRead();
void callbackEventOneCycleMMAPWrite(); void callbackEventOneCycleMMAPWrite();
private:
static void alsaCallbackEvent(void* _userData);
private: private:
ememory::SharedPtr<AlsaPrivate> m_private; ememory::SharedPtr<AlsaPrivate> m_private;
std::vector<audio::orchestra::DeviceInfo> m_devices; etk::Vector<audio::orchestra::DeviceInfo> m_devices;
void saveDeviceInfo(); void saveDeviceInfo();
bool open(uint32_t _device, bool open(uint32_t _device,
enum audio::orchestra::mode _mode, enum audio::orchestra::mode _mode,
@ -62,7 +60,7 @@ namespace audio {
uint32_t *_bufferSize, uint32_t *_bufferSize,
const audio::orchestra::StreamOptions& _options); const audio::orchestra::StreamOptions& _options);
bool openName(const std::string& _deviceName, bool openName(const etk::String& _deviceName,
audio::orchestra::mode _mode, audio::orchestra::mode _mode,
uint32_t _channels, uint32_t _channels,
uint32_t _firstChannel, uint32_t _firstChannel,

View File

@ -13,11 +13,13 @@
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <audio/orchestra/api/AndroidNativeInterface.hpp> #include <audio/orchestra/api/AndroidNativeInterface.hpp>
#include <audio/orchestra/api/Android.hpp> #include <audio/orchestra/api/Android.hpp>
#include <climits> extern "C" {
#include <limits.h>
}
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Android::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Android::create() {
ATA_INFO("Create Android device ... "); ATA_INFO("Create Android device ... ");
return ememory::SharedPtr<audio::orchestra::api::Android>(new audio::orchestra::api::Android()); return ememory::SharedPtr<audio::orchestra::api::Android>(ETK_NEW(audio::orchestra::api::Android));
} }
@ -69,15 +71,15 @@ enum audio::orchestra::error audio::orchestra::api::Android::abortStream() {
void audio::orchestra::api::Android::playback(int16_t* _dst, int32_t _nbChunk) { void audio::orchestra::api::Android::playback(int16_t* _dst, int32_t _nbChunk) {
// clear output buffer: // clear output buffer:
if (_dst != nullptr) { if (_dst != null) {
memset(_dst, 0, _nbChunk*audio::getFormatBytes(m_deviceFormat[modeToIdTable(m_mode)])*m_nDeviceChannels[modeToIdTable(m_mode)]); memset(_dst, 0, _nbChunk*audio::getFormatBytes(m_deviceFormat[modeToIdTable(m_mode)])*m_nDeviceChannels[modeToIdTable(m_mode)]);
} }
int32_t doStopStream = 0; int32_t doStopStream = 0;
audio::Time streamTime = getStreamTime(); audio::Time streamTime = getStreamTime();
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if (m_doConvertBuffer[modeToIdTable(m_mode)] == true) { if (m_doConvertBuffer[modeToIdTable(m_mode)] == true) {
ATA_VERBOSE("Need playback data " << int32_t(_nbChunk) << " userbuffer size = " << m_userBuffer[audio::orchestra::mode_output].size() << "pointer=" << int64_t(&m_userBuffer[audio::orchestra::mode_output][0])); ATA_VERBOSE("Need playback data " << int32_t(_nbChunk) << " userbuffer size = " << m_userBuffer[audio::orchestra::mode_output].size() << "pointer=" << int64_t(&m_userBuffer[audio::orchestra::mode_output][0]));
doStopStream = m_callback(nullptr, doStopStream = m_callback(null,
audio::Time(), audio::Time(),
&m_userBuffer[m_mode][0], &m_userBuffer[m_mode][0],
streamTime, streamTime,
@ -86,7 +88,7 @@ void audio::orchestra::api::Android::playback(int16_t* _dst, int32_t _nbChunk) {
convertBuffer((char*)_dst, (char*)&m_userBuffer[audio::orchestra::mode_output][0], m_convertInfo[audio::orchestra::mode_output]); convertBuffer((char*)_dst, (char*)&m_userBuffer[audio::orchestra::mode_output][0], m_convertInfo[audio::orchestra::mode_output]);
} else { } else {
ATA_VERBOSE("Need playback data " << int32_t(_nbChunk) << " pointer=" << int64_t(_dst)); ATA_VERBOSE("Need playback data " << int32_t(_nbChunk) << " pointer=" << int64_t(_dst));
doStopStream = m_callback(nullptr, doStopStream = m_callback(null,
audio::Time(), audio::Time(),
_dst, _dst,
streamTime, streamTime,
@ -104,13 +106,13 @@ void audio::orchestra::api::Android::playback(int16_t* _dst, int32_t _nbChunk) {
void audio::orchestra::api::Android::record(int16_t* _dst, int32_t _nbChunk) { void audio::orchestra::api::Android::record(int16_t* _dst, int32_t _nbChunk) {
int32_t doStopStream = 0; int32_t doStopStream = 0;
audio::Time streamTime = getStreamTime(); audio::Time streamTime = getStreamTime();
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if (m_doConvertBuffer[modeToIdTable(m_mode)] == true) { if (m_doConvertBuffer[modeToIdTable(m_mode)] == true) {
ATA_VERBOSE("Need playback data " << int32_t(_nbChunk) << " userbuffer size = " << m_userBuffer[audio::orchestra::mode_output].size() << "pointer=" << int64_t(&m_userBuffer[audio::orchestra::mode_output][0])); ATA_VERBOSE("Need playback data " << int32_t(_nbChunk) << " userbuffer size = " << m_userBuffer[audio::orchestra::mode_output].size() << "pointer=" << int64_t(&m_userBuffer[audio::orchestra::mode_output][0]));
convertBuffer((char*)&m_userBuffer[audio::orchestra::mode_input][0], (char*)_dst, m_convertInfo[audio::orchestra::mode_input]); convertBuffer((char*)&m_userBuffer[audio::orchestra::mode_input][0], (char*)_dst, m_convertInfo[audio::orchestra::mode_input]);
doStopStream = m_callback(&m_userBuffer[m_mode][0], doStopStream = m_callback(&m_userBuffer[m_mode][0],
streamTime, streamTime,
nullptr, null,
audio::Time(), audio::Time(),
uint32_t(_nbChunk), uint32_t(_nbChunk),
status); status);
@ -118,7 +120,7 @@ void audio::orchestra::api::Android::record(int16_t* _dst, int32_t _nbChunk) {
ATA_VERBOSE("Need playback data " << int32_t(_nbChunk) << " pointer=" << int64_t(_dst)); ATA_VERBOSE("Need playback data " << int32_t(_nbChunk) << " pointer=" << int64_t(_dst));
doStopStream = m_callback(_dst, doStopStream = m_callback(_dst,
streamTime, streamTime,
nullptr, null,
audio::Time(), audio::Time(),
uint32_t(_nbChunk), uint32_t(_nbChunk),
status); status);

View File

@ -18,7 +18,7 @@ namespace audio {
public: public:
Android(); Android();
virtual ~Android(); virtual ~Android();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typeJava; return audio::orchestra::typeJava;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();
@ -39,7 +39,7 @@ namespace audio {
return m_uid; return m_uid;
} }
private: private:
std::vector<audio::orchestra::DeviceInfo> m_devices; etk::Vector<audio::orchestra::DeviceInfo> m_devices;
void saveDeviceInfo(); void saveDeviceInfo();
bool open(uint32_t _device, bool open(uint32_t _device,
audio::orchestra::mode _mode, audio::orchestra::mode _mode,

View File

@ -4,9 +4,11 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <jni.h> extern "C" {
#include <pthread.h> #include <jni.h>
#include <mutex> #include <pthread.h>
}
#include <ethread/Mutex.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <audio/orchestra/error.hpp> #include <audio/orchestra/error.hpp>
#include <audio/orchestra/api/AndroidNativeInterface.hpp> #include <audio/orchestra/api/AndroidNativeInterface.hpp>
@ -35,19 +37,19 @@ class AndroidOrchestraContext {
private: private:
bool safeInitMethodID(jmethodID& _mid, jclass& _cls, const char* _name, const char* _sign) { bool safeInitMethodID(jmethodID& _mid, jclass& _cls, const char* _name, const char* _sign) {
_mid = m_JavaVirtualMachinePointer->GetMethodID(_cls, _name, _sign); _mid = m_JavaVirtualMachinePointer->GetMethodID(_cls, _name, _sign);
if(_mid == nullptr) { if(_mid == null) {
ATA_ERROR("C->java : Can't find the method " << _name); ATA_ERROR("C->java : Can't find the method " << _name);
/* remove access on the virtual machine : */ /* remove access on the virtual machine : */
m_JavaVirtualMachinePointer = nullptr; m_JavaVirtualMachinePointer = null;
return false; return false;
} }
return true; return true;
} }
bool java_attach_current_thread(int *_rstatus) { bool java_attach_current_thread(int *_rstatus) {
ATA_DEBUG("C->java : call java"); ATA_DEBUG("C->java : call java");
if (jvm_basics::getJavaVM() == nullptr) { if (jvm_basics::getJavaVM() == null) {
ATA_ERROR("C->java : JVM not initialised"); ATA_ERROR("C->java : JVM not initialised");
m_JavaVirtualMachinePointer = nullptr; m_JavaVirtualMachinePointer = null;
return false; return false;
} }
*_rstatus = jvm_basics::getJavaVM()->GetEnv((void **) &m_JavaVirtualMachinePointer, JNI_VERSION_1_6); *_rstatus = jvm_basics::getJavaVM()->GetEnv((void **) &m_JavaVirtualMachinePointer, JNI_VERSION_1_6);
@ -55,12 +57,12 @@ class AndroidOrchestraContext {
JavaVMAttachArgs lJavaVMAttachArgs; JavaVMAttachArgs lJavaVMAttachArgs;
lJavaVMAttachArgs.version = JNI_VERSION_1_6; lJavaVMAttachArgs.version = JNI_VERSION_1_6;
lJavaVMAttachArgs.name = "EwolNativeThread"; lJavaVMAttachArgs.name = "EwolNativeThread";
lJavaVMAttachArgs.group = nullptr; lJavaVMAttachArgs.group = null;
int status = jvm_basics::getJavaVM()->AttachCurrentThread(&m_JavaVirtualMachinePointer, &lJavaVMAttachArgs); int status = jvm_basics::getJavaVM()->AttachCurrentThread(&m_JavaVirtualMachinePointer, &lJavaVMAttachArgs);
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer); jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
if (status != JNI_OK) { if (status != JNI_OK) {
ATA_ERROR("C->java : AttachCurrentThread failed : " << status); ATA_ERROR("C->java : AttachCurrentThread failed : " << status);
m_JavaVirtualMachinePointer = nullptr; m_JavaVirtualMachinePointer = null;
return false; return false;
} }
} }
@ -69,13 +71,13 @@ class AndroidOrchestraContext {
void java_detach_current_thread(int _status) { void java_detach_current_thread(int _status) {
if(_status == JNI_EDETACHED) { if(_status == JNI_EDETACHED) {
jvm_basics::getJavaVM()->DetachCurrentThread(); jvm_basics::getJavaVM()->DetachCurrentThread();
m_JavaVirtualMachinePointer = nullptr; m_JavaVirtualMachinePointer = null;
} }
} }
public: public:
AndroidOrchestraContext(JNIEnv* _env, jclass _classBase, jobject _objCallback) : AndroidOrchestraContext(JNIEnv* _env, jclass _classBase, jobject _objCallback) :
m_JavaVirtualMachinePointer(nullptr), m_JavaVirtualMachinePointer(null),
m_javaClassOrchestra(0), m_javaClassOrchestra(0),
m_javaClassOrchestraCallback(0), m_javaClassOrchestraCallback(0),
m_javaObjectOrchestraCallback(0), m_javaObjectOrchestraCallback(0),
@ -93,7 +95,7 @@ class AndroidOrchestraContext {
ATA_DEBUG("*******************************************"); ATA_DEBUG("*******************************************");
m_JavaVirtualMachinePointer = _env; m_JavaVirtualMachinePointer = _env;
// get default needed all time elements : // get default needed all time elements :
if (m_JavaVirtualMachinePointer == nullptr) { if (m_JavaVirtualMachinePointer == null) {
ATA_ERROR("C->java: NULLPTR jvm interface"); ATA_ERROR("C->java: NULLPTR jvm interface");
return; return;
} }
@ -102,15 +104,15 @@ class AndroidOrchestraContext {
if (m_javaClassOrchestra == 0) { if (m_javaClassOrchestra == 0) {
ATA_ERROR("C->java : Can't find org/musicdsp/orchestra/OrchestraNative class"); ATA_ERROR("C->java : Can't find org/musicdsp/orchestra/OrchestraNative class");
// remove access on the virtual machine : // remove access on the virtual machine :
m_JavaVirtualMachinePointer = nullptr; m_JavaVirtualMachinePointer = null;
return; return;
} }
/* The object field extends Activity and implement OrchestraCallback */ /* The object field extends Activity and implement OrchestraCallback */
m_javaClassOrchestraCallback = m_JavaVirtualMachinePointer->GetObjectClass(_objCallback); m_javaClassOrchestraCallback = m_JavaVirtualMachinePointer->GetObjectClass(_objCallback);
if(m_javaClassOrchestraCallback == nullptr) { if(m_javaClassOrchestraCallback == null) {
ATA_ERROR("C->java : Can't find org/musicdsp/orchestra/OrchestraManagerCallback class"); ATA_ERROR("C->java : Can't find org/musicdsp/orchestra/OrchestraManagerCallback class");
// remove access on the virtual machine : // remove access on the virtual machine :
m_JavaVirtualMachinePointer = nullptr; m_JavaVirtualMachinePointer = null;
return; return;
} }
bool functionCallbackIsMissing = false; bool functionCallbackIsMissing = false;
@ -183,7 +185,7 @@ class AndroidOrchestraContext {
m_javaObjectOrchestraCallback = _env->NewGlobalRef(_objCallback); m_javaObjectOrchestraCallback = _env->NewGlobalRef(_objCallback);
if (m_javaObjectOrchestraCallback == nullptr) { if (m_javaObjectOrchestraCallback == null) {
functionCallbackIsMissing = true; functionCallbackIsMissing = true;
} }
@ -191,7 +193,7 @@ class AndroidOrchestraContext {
if (m_javaDefaultClassString == 0) { if (m_javaDefaultClassString == 0) {
ATA_ERROR("C->java : Can't find java/lang/String" ); ATA_ERROR("C->java : Can't find java/lang/String" );
// remove access on the virtual machine : // remove access on the virtual machine :
m_JavaVirtualMachinePointer = nullptr; m_JavaVirtualMachinePointer = null;
functionCallbackIsMissing = true; functionCallbackIsMissing = true;
} }
if (functionCallbackIsMissing == true) { if (functionCallbackIsMissing == true) {
@ -205,7 +207,7 @@ class AndroidOrchestraContext {
void unInit(JNIEnv* _env) { void unInit(JNIEnv* _env) {
_env->DeleteGlobalRef(m_javaObjectOrchestraCallback); _env->DeleteGlobalRef(m_javaObjectOrchestraCallback);
m_javaObjectOrchestraCallback = nullptr; m_javaObjectOrchestraCallback = null;
} }
uint32_t getDeviceCount() { uint32_t getDeviceCount() {
@ -234,8 +236,8 @@ class AndroidOrchestraContext {
} }
//Call java ... //Call java ...
jstring returnString = (jstring) m_JavaVirtualMachinePointer->CallObjectMethod(m_javaObjectOrchestraCallback, m_javaMethodOrchestraActivityAudioGetDeviceProperty, _idDevice); jstring returnString = (jstring) m_JavaVirtualMachinePointer->CallObjectMethod(m_javaObjectOrchestraCallback, m_javaMethodOrchestraActivityAudioGetDeviceProperty, _idDevice);
const char *js = m_JavaVirtualMachinePointer->GetStringUTFChars(returnString, nullptr); const char *js = m_JavaVirtualMachinePointer->GetStringUTFChars(returnString, null);
std::string retString(js); etk::String retString(js);
m_JavaVirtualMachinePointer->ReleaseStringUTFChars(returnString, js); m_JavaVirtualMachinePointer->ReleaseStringUTFChars(returnString, js);
//m_JavaVirtualMachinePointer->DeleteLocalRef(returnString); //m_JavaVirtualMachinePointer->DeleteLocalRef(returnString);
// manage execption : // manage execption :
@ -256,19 +258,19 @@ class AndroidOrchestraContext {
ejson::Array list = doc["sample-rate"].toArray(); ejson::Array list = doc["sample-rate"].toArray();
if (list.exist() == true) { if (list.exist() == true) {
for (auto it : list) { for (auto it : list) {
info.sampleRates.push_back(int32_t(it.toNumber().get(48000))); info.sampleRates.pushBack(int32_t(it.toNumber().get(48000)));
} }
} }
list = doc["channels"].toArray(); list = doc["channels"].toArray();
if (list.exist() == true) { if (list.exist() == true) {
for (auto it : list) { for (auto it : list) {
info.channels.push_back(audio::getChannelFromString(it.toString().get("???"))); info.channels.pushBack(audio::getChannelFromString(it.toString().get("???")));
} }
} }
list = doc["format"].toArray(); list = doc["format"].toArray();
if (list.exist() == true) { if (list.exist() == true) {
for (auto it : list) { for (auto it : list) {
info.nativeFormats.push_back(audio::getFormatFromString(it.toString().get("???"))); info.nativeFormats.pushBack(audio::getFormatFromString(it.toString().get("???")));
} }
} }
info.isDefault = doc["default"].toBoolean().get(false); info.isDefault = doc["default"].toBoolean().get(false);
@ -276,7 +278,7 @@ class AndroidOrchestraContext {
return info; return info;
} }
private: private:
std::vector<ememory::WeakPtr<audio::orchestra::api::Android> > m_instanceList; // list of connected handle ... etk::Vector<ememory::WeakPtr<audio::orchestra::api::Android> > m_instanceList; // list of connected handle ...
//AndroidAudioCallback m_audioCallBack; //AndroidAudioCallback m_audioCallBack;
//void* m_audioCallBackUserData; //void* m_audioCallBackUserData;
public: public:
@ -305,7 +307,7 @@ class AndroidOrchestraContext {
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer); jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
java_detach_current_thread(status); java_detach_current_thread(status);
if (int32_t(ret) >= 0) { if (int32_t(ret) >= 0) {
m_instanceList.push_back(_instance); m_instanceList.pushBack(_instance);
return int32_t(ret); return int32_t(ret);
} }
return -1; return -1;
@ -369,7 +371,7 @@ class AndroidOrchestraContext {
auto it = m_instanceList.begin(); auto it = m_instanceList.begin();
while (it != m_instanceList.end()) { while (it != m_instanceList.end()) {
auto elem = it->lock(); auto elem = it->lock();
if (elem == nullptr) { if (elem == null) {
it = m_instanceList.erase(it); it = m_instanceList.erase(it);
continue; continue;
} }
@ -383,7 +385,7 @@ class AndroidOrchestraContext {
auto it = m_instanceList.begin(); auto it = m_instanceList.begin();
while (it != m_instanceList.end()) { while (it != m_instanceList.end()) {
auto elem = it->lock(); auto elem = it->lock();
if (elem == nullptr) { if (elem == null) {
it = m_instanceList.erase(it); it = m_instanceList.erase(it);
continue; continue;
} }
@ -400,7 +402,7 @@ static int32_t s_nbContextRequested(0);
uint32_t audio::orchestra::api::android::getDeviceCount() { uint32_t audio::orchestra::api::android::getDeviceCount() {
if (s_localContext == nullptr) { if (s_localContext == null) {
ATA_ERROR("Have no Orchertra API instanciate in JAVA ..."); ATA_ERROR("Have no Orchertra API instanciate in JAVA ...");
return 0; return 0;
} }
@ -408,7 +410,7 @@ uint32_t audio::orchestra::api::android::getDeviceCount() {
} }
audio::orchestra::DeviceInfo audio::orchestra::api::android::getDeviceInfo(uint32_t _device) { audio::orchestra::DeviceInfo audio::orchestra::api::android::getDeviceInfo(uint32_t _device) {
if (s_localContext == nullptr) { if (s_localContext == null) {
return audio::orchestra::DeviceInfo(); return audio::orchestra::DeviceInfo();
} }
return s_localContext->getDeviceInfo(_device); return s_localContext->getDeviceInfo(_device);
@ -423,35 +425,35 @@ int32_t audio::orchestra::api::android::open(uint32_t _device,
uint32_t *_bufferSize, uint32_t *_bufferSize,
const audio::orchestra::StreamOptions& _options, const audio::orchestra::StreamOptions& _options,
ememory::SharedPtr<audio::orchestra::api::Android> _instance) { ememory::SharedPtr<audio::orchestra::api::Android> _instance) {
if (s_localContext == nullptr) { if (s_localContext == null) {
return -1; return -1;
} }
return s_localContext->open(_device, _mode, _channels, _firstChannel, _sampleRate, _format, _bufferSize, _options, _instance); return s_localContext->open(_device, _mode, _channels, _firstChannel, _sampleRate, _format, _bufferSize, _options, _instance);
} }
enum audio::orchestra::error audio::orchestra::api::android::closeStream(int32_t _id) { enum audio::orchestra::error audio::orchestra::api::android::closeStream(int32_t _id) {
if (s_localContext == nullptr) { if (s_localContext == null) {
return audio::orchestra::error_fail; return audio::orchestra::error_fail;
} }
return s_localContext->closeStream(_id); return s_localContext->closeStream(_id);
} }
enum audio::orchestra::error audio::orchestra::api::android::startStream(int32_t _id) { enum audio::orchestra::error audio::orchestra::api::android::startStream(int32_t _id) {
if (s_localContext == nullptr) { if (s_localContext == null) {
return audio::orchestra::error_fail; return audio::orchestra::error_fail;
} }
return s_localContext->startStream(_id); return s_localContext->startStream(_id);
} }
enum audio::orchestra::error audio::orchestra::api::android::stopStream(int32_t _id) { enum audio::orchestra::error audio::orchestra::api::android::stopStream(int32_t _id) {
if (s_localContext == nullptr) { if (s_localContext == null) {
return audio::orchestra::error_fail; return audio::orchestra::error_fail;
} }
return s_localContext->stopStream(_id); return s_localContext->stopStream(_id);
} }
enum audio::orchestra::error audio::orchestra::api::android::abortStream(int32_t _id) { enum audio::orchestra::error audio::orchestra::api::android::abortStream(int32_t _id) {
if (s_localContext == nullptr) { if (s_localContext == null) {
return audio::orchestra::error_fail; return audio::orchestra::error_fail;
} }
return s_localContext->abortStream(_id); return s_localContext->abortStream(_id);
@ -461,15 +463,15 @@ extern "C" {
void Java_org_musicdsp_orchestra_OrchestraNative_NNsetJavaManager(JNIEnv* _env, void Java_org_musicdsp_orchestra_OrchestraNative_NNsetJavaManager(JNIEnv* _env,
jclass _classBase, jclass _classBase,
jobject _objCallback) { jobject _objCallback) {
std::unique_lock<std::mutex> lock(jvm_basics::getMutexJavaVM()); ethread::UniqueLock lock(jvm_basics::getMutexJavaVM());
ATA_INFO("*******************************************"); ATA_INFO("*******************************************");
ATA_INFO("** Creating Orchestra context **"); ATA_INFO("** Creating Orchestra context **");
ATA_INFO("*******************************************"); ATA_INFO("*******************************************");
if (s_localContext != nullptr) { if (s_localContext != null) {
s_nbContextRequested++; s_nbContextRequested++;
} }
s_localContext = ememory::makeShared<AndroidOrchestraContext>(_env, _classBase, _objCallback); s_localContext = ememory::makeShared<AndroidOrchestraContext>(_env, _classBase, _objCallback);
if (s_localContext == nullptr) { if (s_localContext == null) {
ATA_ERROR("Can not allocate the orchestra main context instance"); ATA_ERROR("Can not allocate the orchestra main context instance");
return; return;
} }
@ -477,7 +479,7 @@ extern "C" {
} }
void Java_org_musicdsp_orchestra_OrchestraNative_NNsetJavaManagerRemove(JNIEnv* _env, jclass _cls) { void Java_org_musicdsp_orchestra_OrchestraNative_NNsetJavaManagerRemove(JNIEnv* _env, jclass _cls) {
std::unique_lock<std::mutex> lock(jvm_basics::getMutexJavaVM()); ethread::UniqueLock lock(jvm_basics::getMutexJavaVM());
ATA_INFO("*******************************************"); ATA_INFO("*******************************************");
ATA_INFO("** remove Orchestra Pointer **"); ATA_INFO("** remove Orchestra Pointer **");
ATA_INFO("*******************************************"); ATA_INFO("*******************************************");
@ -495,15 +497,15 @@ extern "C" {
jint _id, jint _id,
jshortArray _location, jshortArray _location,
jint _nbChunk) { jint _nbChunk) {
std::unique_lock<std::mutex> lock(jvm_basics::getMutexJavaVM()); ethread::UniqueLock lock(jvm_basics::getMutexJavaVM());
if (s_localContext == nullptr) { if (s_localContext == null) {
ATA_ERROR("Call audio with no more Low level interface"); ATA_ERROR("Call audio with no more Low level interface");
return; return;
} }
// get the short* pointer from the Java array // get the short* pointer from the Java array
jboolean isCopy; jboolean isCopy;
jshort* dst = _env->GetShortArrayElements(_location, &isCopy); jshort* dst = _env->GetShortArrayElements(_location, &isCopy);
if (dst != nullptr) { if (dst != null) {
//ATA_INFO("Need audioData " << int32_t(_nbChunk)); //ATA_INFO("Need audioData " << int32_t(_nbChunk));
s_localContext->playback(int32_t(_id), static_cast<short*>(dst), int32_t(_nbChunk)); s_localContext->playback(int32_t(_id), static_cast<short*>(dst), int32_t(_nbChunk));
} }
@ -518,15 +520,15 @@ extern "C" {
jint _id, jint _id,
jshortArray _location, jshortArray _location,
jint _nbChunk) { jint _nbChunk) {
std::unique_lock<std::mutex> lock(jvm_basics::getMutexJavaVM()); ethread::UniqueLock lock(jvm_basics::getMutexJavaVM());
if (s_localContext == nullptr) { if (s_localContext == null) {
ATA_ERROR("Call audio with no more Low level interface"); ATA_ERROR("Call audio with no more Low level interface");
return; return;
} }
// get the short* pointer from the Java array // get the short* pointer from the Java array
jboolean isCopy; jboolean isCopy;
jshort* dst = _env->GetShortArrayElements(_location, &isCopy); jshort* dst = _env->GetShortArrayElements(_location, &isCopy);
if (dst != nullptr) { if (dst != null) {
//ATA_INFO("Need audioData " << int32_t(_nbChunk)); //ATA_INFO("Need audioData " << int32_t(_nbChunk));
s_localContext->record(int32_t(_id), static_cast<short*>(dst), int32_t(_nbChunk)); s_localContext->record(int32_t(_id), static_cast<short*>(dst), int32_t(_nbChunk));
} }

View File

@ -12,7 +12,7 @@
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Asio::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Asio::create() {
return ememory::SharedPtr<audio::orchestra::api::Asio>(new audio::orchestra::api::Asio()); return ememory::SharedPtr<audio::orchestra::api::Asio>(ETK_NEW(audio::orchestra::api::Asio));
} }
@ -32,12 +32,13 @@ ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Asio::create()
// on information found in // on information found in
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html. // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html.
#include "asiosys.h" extern "C" {
#include "asio.h" #include "asiosys.h"
#include "iasiothiscallresolver.h" #include "asio.h"
#include "asiodrivers.h" #include "iasiothiscallresolver.h"
#include <cmath> #include "asiodrivers.h"
#include <math.h>
}
static AsioDrivers drivers; static AsioDrivers drivers;
static ASIOCallbacks asioCallbacks; static ASIOCallbacks asioCallbacks;
static ASIODriverInfo driverInfo; static ASIODriverInfo driverInfo;
@ -70,12 +71,12 @@ static void sampleRateChanged(ASIOSampleRate _sRate);
static long asioMessages(long _selector, long _value, void* _message, double* _opt); static long asioMessages(long _selector, long _value, void* _message, double* _opt);
audio::orchestra::api::Asio::Asio() : audio::orchestra::api::Asio::Asio() :
m_private(new audio::orchestra::api::AsioPrivate()) { m_private(ETK_NEW(audio::orchestra::api::AsioPrivate)) {
// ASIO cannot run on a multi-threaded appartment. You can call // ASIO cannot run on a multi-threaded appartment. You can call
// CoInitialize beforehand, but it must be for appartment threading // CoInitialize beforehand, but it must be for appartment threading
// (in which case, CoInitilialize will return S_FALSE here). // (in which case, CoInitilialize will return S_FALSE here).
m_coInitialized = false; m_coInitialized = false;
HRESULT hr = CoInitialize(nullptr); HRESULT hr = CoInitialize(null);
if (FAILED(hr)) { if (FAILED(hr)) {
ATA_ERROR("requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)"); ATA_ERROR("requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)");
} }
@ -154,7 +155,7 @@ rtaudio::DeviceInfo audio::orchestra::api::Asio::getDeviceInfo(uint32_t _device)
for (uint32_t i=0; i<MAX_SAMPLE_RATES; i++) { for (uint32_t i=0; i<MAX_SAMPLE_RATES; i++) {
result = ASIOCanSampleRate((ASIOSampleRate) SAMPLE_RATES[i]); result = ASIOCanSampleRate((ASIOSampleRate) SAMPLE_RATES[i]);
if (result == ASE_OK) { if (result == ASE_OK) {
info.sampleRates.push_back(SAMPLE_RATES[i]); info.sampleRates.pushBack(SAMPLE_RATES[i]);
} }
} }
// Determine supported data types ... just check first channel and assume rest are the same. // Determine supported data types ... just check first channel and assume rest are the same.
@ -173,19 +174,19 @@ rtaudio::DeviceInfo audio::orchestra::api::Asio::getDeviceInfo(uint32_t _device)
info.nativeFormats.clear(); info.nativeFormats.clear();
if ( channelInfo.type == ASIOSTInt16MSB if ( channelInfo.type == ASIOSTInt16MSB
|| channelInfo.type == ASIOSTInt16LSB) { || channelInfo.type == ASIOSTInt16LSB) {
info.nativeFormats.push_back(audio::format_int16); info.nativeFormats.pushBack(audio::format_int16);
} else if ( channelInfo.type == ASIOSTInt32MSB } else if ( channelInfo.type == ASIOSTInt32MSB
|| channelInfo.type == ASIOSTInt32LSB) { || channelInfo.type == ASIOSTInt32LSB) {
info.nativeFormats.push_back(audio::format_int32); info.nativeFormats.pushBack(audio::format_int32);
} else if ( channelInfo.type == ASIOSTFloat32MSB } else if ( channelInfo.type == ASIOSTFloat32MSB
|| channelInfo.type == ASIOSTFloat32LSB) { || channelInfo.type == ASIOSTFloat32LSB) {
info.nativeFormats.push_back(audio::format_float); info.nativeFormats.pushBack(audio::format_float);
} else if ( channelInfo.type == ASIOSTFloat64MSB } else if ( channelInfo.type == ASIOSTFloat64MSB
|| channelInfo.type == ASIOSTFloat64LSB) { || channelInfo.type == ASIOSTFloat64LSB) {
info.nativeFormats.push_back(audio::format_double); info.nativeFormats.pushBack(audio::format_double);
} else if ( channelInfo.type == ASIOSTInt24MSB } else if ( channelInfo.type == ASIOSTInt24MSB
|| channelInfo.type == ASIOSTInt24LSB) { || channelInfo.type == ASIOSTInt24LSB) {
info.nativeFormats.push_back(audio::format_int24); info.nativeFormats.pushBack(audio::format_int24);
} }
if (info.outputChannels > 0){ if (info.outputChannels > 0){
if (getDefaultOutputDevice() == _device) { if (getDefaultOutputDevice() == _device) {
@ -378,10 +379,10 @@ bool audio::orchestra::api::Asio::open(uint32_t _device,
log2_of_max_size = i; log2_of_max_size = i;
} }
} }
long min_delta = std::abs((long)*_bufferSize - ((long)1 << log2_of_min_size)); long min_delta = etk::abs((long)*_bufferSize - ((long)1 << log2_of_min_size));
int32_t min_delta_num = log2_of_min_size; int32_t min_delta_num = log2_of_min_size;
for (int32_t i = log2_of_min_size + 1; i <= log2_of_max_size; i++) { for (int32_t i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
long current_delta = std::abs((long)*_bufferSize - ((long)1 << i)); long current_delta = etk::abs((long)*_bufferSize - ((long)1 << i));
if (current_delta < min_delta) { if (current_delta < min_delta) {
min_delta = current_delta; min_delta = current_delta;
min_delta_num = i; min_delta_num = i;
@ -410,10 +411,10 @@ bool audio::orchestra::api::Asio::open(uint32_t _device,
m_deviceInterleaved[modeToIdTable(_mode)] = false; m_deviceInterleaved[modeToIdTable(_mode)] = false;
m_private->bufferInfos = 0; m_private->bufferInfos = 0;
// Create a manual-reset event. // Create a manual-reset event.
m_private->condition = CreateEvent(nullptr, // no security m_private->condition = CreateEvent(null, // no security
TRUE, // manual-reset TRUE, // manual-reset
FALSE, // non-signaled initially FALSE, // non-signaled initially
nullptr); // unnamed null); // unnamed
// Create the ASIO internal buffers. Since RtAudio sets up input // Create the ASIO internal buffers. Since RtAudio sets up input
// and output separately, we'll have to dispose of previously // and output separately, we'll have to dispose of previously
// created output buffers for a duplex stream. // created output buffers for a duplex stream.
@ -421,16 +422,16 @@ bool audio::orchestra::api::Asio::open(uint32_t _device,
if ( _mode == audio::orchestra::mode_input if ( _mode == audio::orchestra::mode_input
&& m_mode == audio::orchestra::mode_output) { && m_mode == audio::orchestra::mode_output) {
ASIODisposeBuffers(); ASIODisposeBuffers();
if (m_private->bufferInfos == nullptr) { if (m_private->bufferInfos == null) {
free(m_private->bufferInfos); free(m_private->bufferInfos);
m_private->bufferInfos = nullptr; m_private->bufferInfos = null;
} }
} }
// Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure. // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
bool buffersAllocated = false; bool buffersAllocated = false;
uint32_t i, nChannels = m_nDeviceChannels[0] + m_nDeviceChannels[1]; uint32_t i, nChannels = m_nDeviceChannels[0] + m_nDeviceChannels[1];
m_private->bufferInfos = (ASIOBufferInfo *) malloc(nChannels * sizeof(ASIOBufferInfo)); m_private->bufferInfos = (ASIOBufferInfo *) malloc(nChannels * sizeof(ASIOBufferInfo));
if (m_private->bufferInfos == nullptr) { if (m_private->bufferInfos == null) {
ATA_ERROR("error allocating bufferInfo memory for driver (" << driverName << ")."); ATA_ERROR("error allocating bufferInfo memory for driver (" << driverName << ").");
goto error; goto error;
} }
@ -450,7 +451,7 @@ bool audio::orchestra::api::Asio::open(uint32_t _device,
asioCallbacks.bufferSwitch = &bufferSwitch; asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged; asioCallbacks.sampleRateDidChange = &sampleRateChanged;
asioCallbacks.asioMessage = &asioMessages; asioCallbacks.asioMessage = &asioMessages;
asioCallbacks.bufferSwitchTimeInfo = nullptr; asioCallbacks.bufferSwitchTimeInfo = null;
result = ASIOCreateBuffers(m_private->bufferInfos, nChannels, m_bufferSize, &asioCallbacks); result = ASIOCreateBuffers(m_private->bufferInfos, nChannels, m_bufferSize, &asioCallbacks);
if (result != ASE_OK) { if (result != ASE_OK) {
ATA_ERROR("driver (" << driverName << ") error (" << getAsioErrorString(result) << ") creating buffers."); ATA_ERROR("driver (" << driverName << ") error (" << getAsioErrorString(result) << ") creating buffers.");
@ -470,7 +471,7 @@ bool audio::orchestra::api::Asio::open(uint32_t _device,
uint64_t bufferBytes; uint64_t bufferBytes;
bufferBytes = m_nUserChannels[modeToIdTable(_mode)] * *_bufferSize * audio::getFormatBytes(m_userFormat); bufferBytes = m_nUserChannels[modeToIdTable(_mode)] * *_bufferSize * audio::getFormatBytes(m_userFormat);
m_userBuffer[modeToIdTable(_mode)] = (char *) calloc(bufferBytes, 1); m_userBuffer[modeToIdTable(_mode)] = (char *) calloc(bufferBytes, 1);
if (m_userBuffer[modeToIdTable(_mode)] == nullptr) { if (m_userBuffer[modeToIdTable(_mode)] == null) {
ATA_ERROR("error allocating user buffer memory."); ATA_ERROR("error allocating user buffer memory.");
goto error; goto error;
} }
@ -489,10 +490,10 @@ bool audio::orchestra::api::Asio::open(uint32_t _device,
bufferBytes *= *_bufferSize; bufferBytes *= *_bufferSize;
if (m_deviceBuffer) { if (m_deviceBuffer) {
free(m_deviceBuffer); free(m_deviceBuffer);
m_deviceBuffer = nullptr; m_deviceBuffer = null;
} }
m_deviceBuffer = (char *) calloc(bufferBytes, 1); m_deviceBuffer = (char *) calloc(bufferBytes, 1);
if (m_deviceBuffer == nullptr) { if (m_deviceBuffer == null) {
ATA_ERROR("error allocating device buffer memory."); ATA_ERROR("error allocating device buffer memory.");
goto error; goto error;
} }
@ -529,9 +530,9 @@ error:
} }
drivers.removeCurrentDriver(); drivers.removeCurrentDriver();
CloseHandle(m_private->condition); CloseHandle(m_private->condition);
if (m_private->bufferInfos != nullptr) { if (m_private->bufferInfos != null) {
free(m_private->bufferInfos); free(m_private->bufferInfos);
m_private->bufferInfos = nullptr; m_private->bufferInfos = null;
} }
for (int32_t i=0; i<2; i++) { for (int32_t i=0; i<2; i++) {
if (m_userBuffer[i]) { if (m_userBuffer[i]) {
@ -679,7 +680,7 @@ bool audio::orchestra::api::Asio::callbackEvent(long bufferIndex) {
SetEvent(m_private->condition); SetEvent(m_private->condition);
} else { // spawn a thread to stop the stream } else { // spawn a thread to stop the stream
unsigned threadId; unsigned threadId;
m_callbackInfo.thread = _beginthreadex(nullptr, m_callbackInfo.thread = _beginthreadex(null,
0, 0,
&asioStopStream, &asioStopStream,
&m_callbackInfo, &m_callbackInfo,
@ -692,13 +693,13 @@ bool audio::orchestra::api::Asio::callbackEvent(long bufferIndex) {
// draining stream. // draining stream.
if (m_private->drainCounter == 0) { if (m_private->drainCounter == 0) {
audio::Time streamTime = getStreamTime(); audio::Time streamTime = getStreamTime();
std::vector<enum audio::orchestra::status status; etk::Vector<enum audio::orchestra::status status;
if (m_mode != audio::orchestra::mode_input && asioXRun == true) { if (m_mode != audio::orchestra::mode_input && asioXRun == true) {
status.push_back(audio::orchestra::status::underflow); status.pushBack(audio::orchestra::status::underflow);
asioXRun = false; asioXRun = false;
} }
if (m_mode != audio::orchestra::mode_output && asioXRun == true) { if (m_mode != audio::orchestra::mode_output && asioXRun == true) {
status.push_back(audio::orchestra::status::underflow; status.pushBack(audio::orchestra::status::underflow;
asioXRun = false; asioXRun = false;
} }
int32_t cbReturnValue = info->callback(m_userBuffer[1], int32_t cbReturnValue = info->callback(m_userBuffer[1],
@ -711,7 +712,7 @@ bool audio::orchestra::api::Asio::callbackEvent(long bufferIndex) {
m_state = audio::orchestra::state::stopping; m_state = audio::orchestra::state::stopping;
m_private->drainCounter = 2; m_private->drainCounter = 2;
unsigned threadId; unsigned threadId;
m_callbackInfo.thread = _beginthreadex(nullptr, m_callbackInfo.thread = _beginthreadex(null,
0, 0,
&asioStopStream, &asioStopStream,
&m_callbackInfo, &m_callbackInfo,

View File

@ -17,7 +17,7 @@ namespace audio {
public: public:
Asio(); Asio();
virtual ~Asio(); virtual ~Asio();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typeAsio; return audio::orchestra::typeAsio;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();
@ -34,7 +34,7 @@ namespace audio {
bool callbackEvent(long _bufferIndex); bool callbackEvent(long _bufferIndex);
private: private:
ememory::SharedPtr<AsioPrivate> m_private; ememory::SharedPtr<AsioPrivate> m_private;
std::vector<audio::orchestra::DeviceInfo> m_devices; etk::Vector<audio::orchestra::DeviceInfo> m_devices;
void saveDeviceInfo(); void saveDeviceInfo();
bool m_coInitialized; bool m_coInitialized;
bool open(uint32_t _device, bool open(uint32_t _device,

View File

@ -16,12 +16,12 @@
#include <audio/orchestra/Interface.hpp> #include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <thread> #include <ethread/Thread.hpp>
#include <ethread/tools.hpp> #include <ethread/tools.hpp>
#include <audio/orchestra/api/Core.hpp> #include <audio/orchestra/api/Core.hpp>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Core::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Core::create() {
return ememory::SharedPtr<audio::orchestra::api::Core>(new audio::orchestra::api::Core()); return ememory::SharedPtr<audio::orchestra::api::Core>(ETK_NEW(audio::orchestra::api::Core));
} }
namespace audio { namespace audio {
@ -37,7 +37,7 @@ namespace audio {
uint32_t nStreams[2]; // number of streams to use uint32_t nStreams[2]; // number of streams to use
bool xrun[2]; bool xrun[2];
char *deviceBuffer; char *deviceBuffer;
std::condition_variable condition; ethread::Semaphore m_semaphore;
int32_t drainCounter; // Tracks callback counts when draining int32_t drainCounter; // Tracks callback counts when draining
bool internalDrain; // Indicates if stop is initiated from callback or not. bool internalDrain; // Indicates if stop is initiated from callback or not.
CorePrivate() : CorePrivate() :
@ -57,13 +57,13 @@ namespace audio {
} }
audio::orchestra::api::Core::Core() : audio::orchestra::api::Core::Core() :
m_private(new audio::orchestra::api::CorePrivate()) { m_private(ETK_NEW(audio::orchestra::api::CorePrivate)) {
#if defined(AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER) #if defined(AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER)
// This is a largely undocumented but absolutely necessary // This is a largely undocumented but absolutely necessary
// requirement starting with OS-X 10.6. If not called, queries and // requirement starting with OS-X 10.6. If not called, queries and
// updates to various audio device properties are not handled // updates to various audio device properties are not handled
// correctly. // correctly.
CFRunLoopRef theRunLoop = nullptr; CFRunLoopRef theRunLoop = null;
AudioObjectPropertyAddress property = { AudioObjectPropertyAddress property = {
kAudioHardwarePropertyRunLoop, kAudioHardwarePropertyRunLoop,
kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyScopeGlobal,
@ -72,7 +72,7 @@ audio::orchestra::api::Core::Core() :
OSStatus result = AudioObjectSetPropertyData(kAudioObjectSystemObject, OSStatus result = AudioObjectSetPropertyData(kAudioObjectSystemObject,
&property, &property,
0, 0,
nullptr, null,
sizeof(CFRunLoopRef), sizeof(CFRunLoopRef),
&theRunLoop); &theRunLoop);
if (result != noErr) { if (result != noErr) {
@ -98,7 +98,7 @@ uint32_t audio::orchestra::api::Core::getDeviceCount() {
kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster kAudioObjectPropertyElementMaster
}; };
OSStatus result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &dataSize); OSStatus result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, null, &dataSize);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("OS-X error getting device info!"); ATA_ERROR("OS-X error getting device info!");
return 0; return 0;
@ -121,7 +121,7 @@ uint32_t audio::orchestra::api::Core::getDefaultInputDevice() {
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&property, &property,
0, 0,
nullptr, null,
&dataSize, &dataSize,
&id); &id);
if (result != noErr) { if (result != noErr) {
@ -134,7 +134,7 @@ uint32_t audio::orchestra::api::Core::getDefaultInputDevice() {
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&property, &property,
0, 0,
nullptr, null,
&dataSize, &dataSize,
(void*)&deviceList); (void*)&deviceList);
if (result != noErr) { if (result != noErr) {
@ -165,7 +165,7 @@ uint32_t audio::orchestra::api::Core::getDefaultOutputDevice() {
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&property, &property,
0, 0,
nullptr, null,
&dataSize, &dataSize,
&id); &id);
if (result != noErr) { if (result != noErr) {
@ -178,7 +178,7 @@ uint32_t audio::orchestra::api::Core::getDefaultOutputDevice() {
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&property, &property,
0, 0,
nullptr, null,
&dataSize, &dataSize,
(void*)&deviceList); (void*)&deviceList);
if (result != noErr) { if (result != noErr) {
@ -223,7 +223,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&property, &property,
0, 0,
nullptr, null,
&dataSize, &dataSize,
(void*)&deviceList); (void*)&deviceList);
if (result != noErr) { if (result != noErr) {
@ -239,7 +239,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
CFStringRef cfname; CFStringRef cfname;
dataSize = sizeof(CFStringRef); dataSize = sizeof(CFStringRef);
property.mSelector = kAudioObjectPropertyManufacturer; property.mSelector = kAudioObjectPropertyManufacturer;
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &cfname); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, &cfname);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting device manufacturer."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting device manufacturer.");
info.clear(); info.clear();
@ -247,14 +247,14 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
} }
//const char *mname = CFStringGetCStringPtr(cfname, CFStringGetSystemEncoding()); //const char *mname = CFStringGetCStringPtr(cfname, CFStringGetSystemEncoding());
int32_t length = CFStringGetLength(cfname); int32_t length = CFStringGetLength(cfname);
std::vector<char> name; etk::Vector<char> name;
name.resize(length * 3 + 1, '\0'); name.resize(length * 3 + 1, '\0');
CFStringGetCString(cfname, &name[0], length * 3 + 1, CFStringGetSystemEncoding()); CFStringGetCString(cfname, &name[0], length * 3 + 1, CFStringGetSystemEncoding());
info.name.append(&name[0], strlen(&name[0])); info.name.append(&name[0], strlen(&name[0]));
info.name.append(": "); info.name.append(": ");
CFRelease(cfname); CFRelease(cfname);
property.mSelector = kAudioObjectPropertyName; property.mSelector = kAudioObjectPropertyName;
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &cfname); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, &cfname);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting device name."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting device name.");
info.clear(); info.clear();
@ -276,9 +276,9 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
} else { } else {
property.mScope = kAudioDevicePropertyScopeInput; property.mScope = kAudioDevicePropertyScopeInput;
} }
AudioBufferList *bufferList = nullptr; AudioBufferList *bufferList = null;
dataSize = 0; dataSize = 0;
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize); result = AudioObjectGetPropertyDataSize(id, &property, 0, null, &dataSize);
if (result != noErr || dataSize == 0) { if (result != noErr || dataSize == 0) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream configuration info for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream configuration info for device (" << _device << ").");
info.clear(); info.clear();
@ -286,12 +286,12 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
} }
// Allocate the AudioBufferList. // Allocate the AudioBufferList.
bufferList = (AudioBufferList *) malloc(dataSize); bufferList = (AudioBufferList *) malloc(dataSize);
if (bufferList == nullptr) { if (bufferList == null) {
ATA_ERROR("memory error allocating AudioBufferList."); ATA_ERROR("memory error allocating AudioBufferList.");
info.clear(); info.clear();
return info; return info;
} }
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, bufferList); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, bufferList);
if ( result != noErr if ( result != noErr
|| dataSize == 0) { || dataSize == 0) {
free(bufferList); free(bufferList);
@ -302,7 +302,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
// Get channel information. // Get channel information.
for (size_t iii=0; iii<bufferList->mNumberBuffers; ++iii) { for (size_t iii=0; iii<bufferList->mNumberBuffers; ++iii) {
for (size_t jjj=0; jjj<bufferList->mBuffers[iii].mNumberChannels; ++jjj) { for (size_t jjj=0; jjj<bufferList->mBuffers[iii].mNumberChannels; ++jjj) {
info.channels.push_back(audio::channel_unknow); info.channels.pushBack(audio::channel_unknow);
} }
} }
free(bufferList); free(bufferList);
@ -316,7 +316,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
// Determine the supported sample rates. // Determine the supported sample rates.
// ------------------------------------------------ // ------------------------------------------------
property.mSelector = kAudioDevicePropertyAvailableNominalSampleRates; property.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize); result = AudioObjectGetPropertyDataSize(id, &property, 0, null, &dataSize);
if ( result != kAudioHardwareNoError if ( result != kAudioHardwareNoError
|| dataSize == 0) { || dataSize == 0) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting sample rate info."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting sample rate info.");
@ -325,7 +325,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
} }
uint32_t nRanges = dataSize / sizeof(AudioValueRange); uint32_t nRanges = dataSize / sizeof(AudioValueRange);
AudioValueRange rangeList[ nRanges ]; AudioValueRange rangeList[ nRanges ];
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &rangeList); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, &rangeList);
if (result != kAudioHardwareNoError) { if (result != kAudioHardwareNoError) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting sample rates."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting sample rates.");
info.clear(); info.clear();
@ -344,7 +344,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
for (auto &it : audio::orchestra::genericSampleRate()) { for (auto &it : audio::orchestra::genericSampleRate()) {
if ( it >= minimumRate if ( it >= minimumRate
&& it <= maximumRate) { && it <= maximumRate) {
info.sampleRates.push_back(it); info.sampleRates.pushBack(it);
} }
} }
if (info.sampleRates.size() == 0) { if (info.sampleRates.size() == 0) {
@ -358,7 +358,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Core::getDeviceInfo(uint32_t
// CoreAudio always uses 32-bit floating point data for PCM streams. // CoreAudio always uses 32-bit floating point data for PCM streams.
// Thus, any other "physical" formats supported by the device are of // Thus, any other "physical" formats supported by the device are of
// no interest to the client. // no interest to the client.
info.nativeFormats.push_back(audio::format_float); info.nativeFormats.pushBack(audio::format_float);
// ------------------------------------------------ // ------------------------------------------------
// Determine the default channel. // Determine the default channel.
// ------------------------------------------------ // ------------------------------------------------
@ -386,10 +386,10 @@ OSStatus audio::orchestra::api::Core::callbackEvent(AudioDeviceID _inDevice,
audio::orchestra::api::Core* myClass = reinterpret_cast<audio::orchestra::api::Core*>(_userData); audio::orchestra::api::Core* myClass = reinterpret_cast<audio::orchestra::api::Core*>(_userData);
audio::Time inputTime; audio::Time inputTime;
audio::Time outputTime; audio::Time outputTime;
if (_inInputTime != nullptr) { if (_inInputTime != null) {
inputTime = audio::Time(_inInputTime->mHostTime/1000000000LL, _inInputTime->mHostTime%1000000000LL); inputTime = audio::Time(_inInputTime->mHostTime/1000000000LL, _inInputTime->mHostTime%1000000000LL);
} }
if (_inOutputTime != nullptr) { if (_inOutputTime != null) {
outputTime = audio::Time(_inOutputTime->mHostTime/1000000000LL, _inOutputTime->mHostTime%1000000000LL); outputTime = audio::Time(_inOutputTime->mHostTime/1000000000LL, _inOutputTime->mHostTime%1000000000LL);
} }
if (myClass->callbackEvent(_inDevice, _inInputData, inputTime, _outOutputData, outputTime) == false) { if (myClass->callbackEvent(_inDevice, _inInputData, inputTime, _outOutputData, outputTime) == false) {
@ -427,7 +427,7 @@ static OSStatus rateListener(AudioObjectID _inDevice,
kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster kAudioObjectPropertyElementMaster
}; };
AudioObjectGetPropertyData(_inDevice, &property, 0, nullptr, &dataSize, rate); AudioObjectGetPropertyData(_inDevice, &property, 0, null, &dataSize, rate);
return kAudioHardwareNoError; return kAudioHardwareNoError;
} }
@ -461,7 +461,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&property, &property,
0, 0,
nullptr, null,
&dataSize, &dataSize,
(void *) &deviceList); (void *) &deviceList);
if (result != noErr) { if (result != noErr) {
@ -481,7 +481,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
AudioBufferList *bufferList = nil; AudioBufferList *bufferList = nil;
dataSize = 0; dataSize = 0;
property.mSelector = kAudioDevicePropertyStreamConfiguration; property.mSelector = kAudioDevicePropertyStreamConfiguration;
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize); result = AudioObjectGetPropertyDataSize(id, &property, 0, null, &dataSize);
if ( result != noErr if ( result != noErr
|| dataSize == 0) { || dataSize == 0) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream configuration info for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream configuration info for device (" << _device << ").");
@ -489,11 +489,11 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
} }
// Allocate the AudioBufferList. // Allocate the AudioBufferList.
bufferList = (AudioBufferList *) malloc(dataSize); bufferList = (AudioBufferList *) malloc(dataSize);
if (bufferList == nullptr) { if (bufferList == null) {
ATA_ERROR("memory error allocating AudioBufferList."); ATA_ERROR("memory error allocating AudioBufferList.");
return false; return false;
} }
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, bufferList); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, bufferList);
if ( result != noErr if ( result != noErr
|| dataSize == 0) { || dataSize == 0) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream configuration for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream configuration for device (" << _device << ").");
@ -569,7 +569,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
AudioValueRange bufferRange; AudioValueRange bufferRange;
dataSize = sizeof(AudioValueRange); dataSize = sizeof(AudioValueRange);
property.mSelector = kAudioDevicePropertyBufferFrameSizeRange; property.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &bufferRange); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, &bufferRange);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting buffer size range for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting buffer size range for device (" << _device << ").");
return false; return false;
@ -587,7 +587,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
uint32_t theSize = (uint32_t) *_bufferSize; uint32_t theSize = (uint32_t) *_bufferSize;
dataSize = sizeof(uint32_t); dataSize = sizeof(uint32_t);
property.mSelector = kAudioDevicePropertyBufferFrameSize; property.mSelector = kAudioDevicePropertyBufferFrameSize;
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &theSize); result = AudioObjectSetPropertyData(id, &property, 0, null, dataSize, &theSize);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") setting the buffer size for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") setting the buffer size for device (" << _device << ").");
return false; return false;
@ -607,7 +607,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
double nominalRate; double nominalRate;
dataSize = sizeof(double); dataSize = sizeof(double);
property.mSelector = kAudioDevicePropertyNominalSampleRate; property.mSelector = kAudioDevicePropertyNominalSampleRate;
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &nominalRate); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, &nominalRate);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting current sample rate."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting current sample rate.");
return false; return false;
@ -623,7 +623,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
return false; return false;
} }
nominalRate = (double) _sampleRate; nominalRate = (double) _sampleRate;
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &nominalRate); result = AudioObjectSetPropertyData(id, &property, 0, null, dataSize, &nominalRate);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") setting sample rate for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") setting sample rate for device (" << _device << ").");
return false; return false;
@ -635,7 +635,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
if (microCounter > 5000000) { if (microCounter > 5000000) {
break; break;
} }
std::this_thread::sleep_for(std::chrono::milliseconds(5)); ethread::sleepMilliSeconds((5));
} }
// Remove the property listener. // Remove the property listener.
AudioObjectRemovePropertyListener(id, &tmp, &rateListener, (void *) &reportedRate); AudioObjectRemovePropertyListener(id, &tmp, &rateListener, (void *) &reportedRate);
@ -649,7 +649,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
AudioStreamBasicDescription description; AudioStreamBasicDescription description;
dataSize = sizeof(AudioStreamBasicDescription); dataSize = sizeof(AudioStreamBasicDescription);
property.mSelector = kAudioStreamPropertyVirtualFormat; property.mSelector = kAudioStreamPropertyVirtualFormat;
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &description); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, &description);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream format for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream format for device (" << _device << ").");
return false; return false;
@ -667,7 +667,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
updateFormat = true; updateFormat = true;
} }
if (updateFormat) { if (updateFormat) {
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &description); result = AudioObjectSetPropertyData(id, &property, 0, null, dataSize, &description);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") setting sample rate or data format for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") setting sample rate or data format for device (" << _device << ").");
return false; return false;
@ -675,16 +675,16 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
} }
// Now check the physical format. // Now check the physical format.
property.mSelector = kAudioStreamPropertyPhysicalFormat; property.mSelector = kAudioStreamPropertyPhysicalFormat;
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &description); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, &description);
if (result != noErr) { if (result != noErr) {
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream physical format for device (" << _device << ")."); ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream physical format for device (" << _device << ").");
return false; return false;
} }
//std::cout << "Current physical stream format:" << std::endl; //ATA_DEBUG("Current physical stream format:");
//std::cout << " mBitsPerChan = " << description.mBitsPerChannel << std::endl; //ATA_DEBUG(" mBitsPerChan = " << description.mBitsPerChannel);
//std::cout << " aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl; //ATA_DEBUG(" aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked));
//std::cout << " bytesPerFrame = " << description.mBytesPerFrame << std::endl; //ATA_DEBUG(" bytesPerFrame = " << description.mBytesPerFrame);
//std::cout << " sample rate = " << description.mSampleRate << std::endl; //ATA_DEBUG(" sample rate = " << description.mSampleRate);
if ( description.mFormatID != kAudioFormatLinearPCM if ( description.mFormatID != kAudioFormatLinearPCM
|| description.mBitsPerChannel < 16) { || description.mBitsPerChannel < 16) {
description.mFormatID = kAudioFormatLinearPCM; description.mFormatID = kAudioFormatLinearPCM;
@ -692,19 +692,19 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
AudioStreamBasicDescription testDescription = description; AudioStreamBasicDescription testDescription = description;
uint32_t formatFlags; uint32_t formatFlags;
// We'll try higher bit rates first and then work our way down. // We'll try higher bit rates first and then work our way down.
std::vector< std::pair<uint32_t, uint32_t> > physicalFormats; etk::Vector< etk::Pair<uint32_t, uint32_t> > physicalFormats;
formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsFloat) & ~kLinearPCMFormatFlagIsSignedInteger; formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsFloat) & ~kLinearPCMFormatFlagIsSignedInteger;
physicalFormats.push_back(std::pair<float, uint32_t>(32, formatFlags)); physicalFormats.pushBack(etk::Pair<float, uint32_t>(32, formatFlags));
formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat; formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
physicalFormats.push_back(std::pair<float, uint32_t>(32, formatFlags)); physicalFormats.pushBack(etk::Pair<float, uint32_t>(32, formatFlags));
physicalFormats.push_back(std::pair<float, uint32_t>(24, formatFlags)); // 24-bit packed physicalFormats.pushBack(etk::Pair<float, uint32_t>(24, formatFlags)); // 24-bit packed
formatFlags &= ~(kAudioFormatFlagIsPacked | kAudioFormatFlagIsAlignedHigh); formatFlags &= ~(kAudioFormatFlagIsPacked | kAudioFormatFlagIsAlignedHigh);
physicalFormats.push_back(std::pair<float, uint32_t>(24.2, formatFlags)); // 24-bit in 4 bytes, aligned low physicalFormats.pushBack(etk::Pair<float, uint32_t>(24.2, formatFlags)); // 24-bit in 4 bytes, aligned low
formatFlags |= kAudioFormatFlagIsAlignedHigh; formatFlags |= kAudioFormatFlagIsAlignedHigh;
physicalFormats.push_back(std::pair<float, uint32_t>(24.4, formatFlags)); // 24-bit in 4 bytes, aligned high physicalFormats.pushBack(etk::Pair<float, uint32_t>(24.4, formatFlags)); // 24-bit in 4 bytes, aligned high
formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat; formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
physicalFormats.push_back(std::pair<float, uint32_t>(16, formatFlags)); physicalFormats.pushBack(etk::Pair<float, uint32_t>(16, formatFlags));
physicalFormats.push_back(std::pair<float, uint32_t>(8, formatFlags)); physicalFormats.pushBack(etk::Pair<float, uint32_t>(8, formatFlags));
bool setPhysicalFormat = false; bool setPhysicalFormat = false;
for(uint32_t i=0; i<physicalFormats.size(); i++) { for(uint32_t i=0; i<physicalFormats.size(); i++) {
testDescription = description; testDescription = description;
@ -717,14 +717,14 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
testDescription.mBytesPerFrame = testDescription.mBitsPerChannel/8 * testDescription.mChannelsPerFrame; testDescription.mBytesPerFrame = testDescription.mBitsPerChannel/8 * testDescription.mChannelsPerFrame;
} }
testDescription.mBytesPerPacket = testDescription.mBytesPerFrame * testDescription.mFramesPerPacket; testDescription.mBytesPerPacket = testDescription.mBytesPerFrame * testDescription.mFramesPerPacket;
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &testDescription); result = AudioObjectSetPropertyData(id, &property, 0, null, dataSize, &testDescription);
if (result == noErr) { if (result == noErr) {
setPhysicalFormat = true; setPhysicalFormat = true;
//std::cout << "Updated physical stream format:" << std::endl; //ATA_DEBUG("Updated physical stream format:");
//std::cout << " mBitsPerChan = " << testDescription.mBitsPerChannel << std::endl; //ATA_DEBUG(" mBitsPerChan = " << testDescription.mBitsPerChannel);
//std::cout << " aligned high = " << (testDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (testDescription.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl; //ATA_DEBUG(" aligned high = " << (testDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (testDescription.mFormatFlags & kAudioFormatFlagIsPacked));
//std::cout << " bytesPerFrame = " << testDescription.mBytesPerFrame << std::endl; //ATA_DEBUG(" bytesPerFrame = " << testDescription.mBytesPerFrame);
//std::cout << " sample rate = " << testDescription.mSampleRate << std::endl; //ATA_DEBUG(" sample rate = " << testDescription.mSampleRate);
break; break;
} }
} }
@ -738,7 +738,7 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
dataSize = sizeof(uint32_t); dataSize = sizeof(uint32_t);
property.mSelector = kAudioDevicePropertyLatency; property.mSelector = kAudioDevicePropertyLatency;
if (AudioObjectHasProperty(id, &property) == true) { if (AudioObjectHasProperty(id, &property) == true) {
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &latency); result = AudioObjectGetPropertyData(id, &property, 0, null, &dataSize, &latency);
if (result == kAudioHardwareNoError) { if (result == kAudioHardwareNoError) {
m_latency[ _mode ] = latency; m_latency[ _mode ] = latency;
} else { } else {
@ -814,10 +814,10 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
bufferBytes *= *_bufferSize; bufferBytes *= *_bufferSize;
if (m_deviceBuffer) { if (m_deviceBuffer) {
free(m_deviceBuffer); free(m_deviceBuffer);
m_deviceBuffer = nullptr; m_deviceBuffer = null;
} }
m_deviceBuffer = (char *) calloc(bufferBytes, 1); m_deviceBuffer = (char *) calloc(bufferBytes, 1);
if (m_deviceBuffer == nullptr) { if (m_deviceBuffer == null) {
ATA_ERROR("error allocating device buffer memory."); ATA_ERROR("error allocating device buffer memory.");
goto error; goto error;
} }
@ -908,7 +908,7 @@ enum audio::orchestra::error audio::orchestra::api::Core::closeStream() {
m_userBuffer[1].clear(); m_userBuffer[1].clear();
if (m_deviceBuffer) { if (m_deviceBuffer) {
free(m_deviceBuffer); free(m_deviceBuffer);
m_deviceBuffer = nullptr; m_deviceBuffer = null;
} }
m_mode = audio::orchestra::mode_unknow; m_mode = audio::orchestra::mode_unknow;
m_state = audio::orchestra::state::closed; m_state = audio::orchestra::state::closed;
@ -967,9 +967,9 @@ enum audio::orchestra::error audio::orchestra::api::Core::stopStream() {
if ( m_mode == audio::orchestra::mode_output if ( m_mode == audio::orchestra::mode_output
|| m_mode == audio::orchestra::mode_duplex) { || m_mode == audio::orchestra::mode_duplex) {
if (m_private->drainCounter == 0) { if (m_private->drainCounter == 0) {
std::unique_lock<std::mutex> lck(m_mutex); ethread::UniqueLock lck(m_mutex);
m_private->drainCounter = 2; m_private->drainCounter = 2;
m_private->condition.wait(lck); m_private->m_semaphore.wait();
} }
result = AudioDeviceStop(m_private->id[0], &audio::orchestra::api::Core::callbackEvent); result = AudioDeviceStop(m_private->id[0], &audio::orchestra::api::Core::callbackEvent);
if (result != noErr) { if (result != noErr) {
@ -1036,10 +1036,10 @@ bool audio::orchestra::api::Core::callbackEvent(AudioDeviceID _deviceId,
m_state = audio::orchestra::state::stopping; m_state = audio::orchestra::state::stopping;
ATA_VERBOSE("Set state as stopping"); ATA_VERBOSE("Set state as stopping");
if (m_private->internalDrain == true) { if (m_private->internalDrain == true) {
new std::thread(&audio::orchestra::api::Core::coreStopStream, this); ETK_NEW(ethread::Thread, &audio::orchestra::api::Core::coreStopStream, this);
} else { } else {
// external call to stopStream() // external call to stopStream()
m_private->condition.notify_one(); m_private->m_semaphore.post();
} }
return true; return true;
} }
@ -1048,15 +1048,15 @@ bool audio::orchestra::api::Core::callbackEvent(AudioDeviceID _deviceId,
// draining stream or duplex mode AND the input/output devices are // draining stream or duplex mode AND the input/output devices are
// different AND this function is called for the input device. // different AND this function is called for the input device.
if (m_private->drainCounter == 0 && (m_mode != audio::orchestra::mode_duplex || _deviceId == outputDevice)) { if (m_private->drainCounter == 0 && (m_mode != audio::orchestra::mode_duplex || _deviceId == outputDevice)) {
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if ( m_mode != audio::orchestra::mode_input if ( m_mode != audio::orchestra::mode_input
&& m_private->xrun[0] == true) { && m_private->xrun[0] == true) {
status.push_back(audio::orchestra::status::underflow); status.pushBack(audio::orchestra::status::underflow);
m_private->xrun[0] = false; m_private->xrun[0] = false;
} }
if ( m_mode != audio::orchestra::mode_output if ( m_mode != audio::orchestra::mode_output
&& m_private->xrun[1] == true) { && m_private->xrun[1] == true) {
status.push_back(audio::orchestra::status::overflow); status.pushBack(audio::orchestra::status::overflow);
m_private->xrun[1] = false; m_private->xrun[1] = false;
} }
int32_t cbReturnValue = m_callback(&m_userBuffer[1][0], int32_t cbReturnValue = m_callback(&m_userBuffer[1][0],

View File

@ -20,7 +20,7 @@ namespace audio {
public: public:
Core(); Core();
virtual ~Core(); virtual ~Core();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typeCoreOSX; return audio::orchestra::typeCoreOSX;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();

View File

@ -17,7 +17,7 @@ namespace audio {
public: public:
CoreIos(); CoreIos();
virtual ~CoreIos(); virtual ~CoreIos();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typeCoreIOS; return audio::orchestra::typeCoreIOS;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();
@ -32,7 +32,7 @@ namespace audio {
// will most likely produce highly undesireable results! // will most likely produce highly undesireable results!
void callbackEvent(); void callbackEvent();
private: private:
std::vector<audio::orchestra::DeviceInfo> m_devices; etk::Vector<audio::orchestra::DeviceInfo> m_devices;
void saveDeviceInfo(); void saveDeviceInfo();
bool open(uint32_t _device, bool open(uint32_t _device,
audio::orchestra::mode _mode, audio::orchestra::mode _mode,

View File

@ -13,12 +13,14 @@
#include <audio/orchestra/Interface.hpp> #include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <climits> extern "C" {
#include <limits.h>
}
#include <audio/orchestra/api/CoreIos.hpp> #include <audio/orchestra/api/CoreIos.hpp>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::CoreIos::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::CoreIos::create() {
ATA_INFO("Create CoreIos device ... "); ATA_INFO("Create CoreIos device ... ");
return ememory::SharedPtr<audio::orchestra::api::CoreIos>(new audio::orchestra::api::CoreIos()); return ememory::SharedPtr<audio::orchestra::api::CoreIos>(ETK_NEW(audio::orchestra::api::CoreIos));
} }
#define kOutputBus 0 #define kOutputBus 0
@ -38,7 +40,7 @@ namespace audio {
audio::orchestra::api::CoreIos::CoreIos() : audio::orchestra::api::CoreIos::CoreIos() :
m_private(new audio::orchestra::api::CoreIosPrivate()) { m_private(ETK_NEW(audio::orchestra::api::CoreIosPrivate)) {
ATA_INFO("new CoreIos"); ATA_INFO("new CoreIos");
int32_t deviceCount = 2; int32_t deviceCount = 2;
ATA_ERROR("Get count devices : " << 2); ATA_ERROR("Get count devices : " << 2);
@ -132,12 +134,12 @@ void audio::orchestra::api::CoreIos::callBackEvent(void* _data,
int32_t _nbChunk, int32_t _nbChunk,
const audio::Time& _time) { const audio::Time& _time) {
int32_t doStopStream = 0; int32_t doStopStream = 0;
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if ( m_mode == audio::orchestra::mode_output if ( m_mode == audio::orchestra::mode_output
|| m_mode == audio::orchestra::mode_duplex) { || m_mode == audio::orchestra::mode_duplex) {
if (m_doConvertBuffer[modeToIdTable(audio::orchestra::mode_output)] == true) { if (m_doConvertBuffer[modeToIdTable(audio::orchestra::mode_output)] == true) {
ATA_INFO("get output DATA : " << uint64_t(&m_userBuffer[modeToIdTable(audio::orchestra::mode_output)][0])); ATA_INFO("get output DATA : " << uint64_t(&m_userBuffer[modeToIdTable(audio::orchestra::mode_output)][0]));
doStopStream = m_callback(nullptr, doStopStream = m_callback(null,
audio::Time(), audio::Time(),
&m_userBuffer[modeToIdTable(audio::orchestra::mode_output)][0], &m_userBuffer[modeToIdTable(audio::orchestra::mode_output)][0],
_time, _time,
@ -146,7 +148,7 @@ void audio::orchestra::api::CoreIos::callBackEvent(void* _data,
convertBuffer((char*)_data, &m_userBuffer[modeToIdTable(audio::orchestra::mode_output)][0], m_convertInfo[modeToIdTable(audio::orchestra::mode_output)]); convertBuffer((char*)_data, &m_userBuffer[modeToIdTable(audio::orchestra::mode_output)][0], m_convertInfo[modeToIdTable(audio::orchestra::mode_output)]);
} else { } else {
ATA_INFO("have output DATA : " << uint64_t(_data)); ATA_INFO("have output DATA : " << uint64_t(_data));
doStopStream = m_callback(nullptr, doStopStream = m_callback(null,
_time, _time,
_data, _data,
audio::Time(), audio::Time(),
@ -159,7 +161,7 @@ void audio::orchestra::api::CoreIos::callBackEvent(void* _data,
ATA_INFO("have input DATA : " << uint64_t(_data)); ATA_INFO("have input DATA : " << uint64_t(_data));
doStopStream = m_callback(_data, doStopStream = m_callback(_data,
_time, _time,
nullptr, null,
audio::Time(), audio::Time(),
_nbChunk, _nbChunk,
status); status);
@ -178,12 +180,12 @@ static OSStatus playbackCallback(void *_userData,
uint32_t _inBusNumber, uint32_t _inBusNumber,
uint32_t _inNumberFrames, uint32_t _inNumberFrames,
AudioBufferList* _ioData) { AudioBufferList* _ioData) {
if (_userData == nullptr) { if (_userData == null) {
ATA_ERROR("callback event ... nullptr pointer"); ATA_ERROR("callback event ... null pointer");
return -1; return -1;
} }
audio::Time tmpTimeime; audio::Time tmpTimeime;
if (_inTime != nullptr) { if (_inTime != null) {
tmpTimeime = audio::Time(_inTime->mHostTime/1000000000LL, _inTime->mHostTime%1000000000LL); tmpTimeime = audio::Time(_inTime->mHostTime/1000000000LL, _inTime->mHostTime%1000000000LL);
} }
audio::orchestra::api::CoreIos* myClass = static_cast<audio::orchestra::api::CoreIos*>(_userData); audio::orchestra::api::CoreIos* myClass = static_cast<audio::orchestra::api::CoreIos*>(_userData);
@ -265,7 +267,7 @@ bool audio::orchestra::api::CoreIos::open(uint32_t _device,
desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentManufacturer = kAudioUnitManufacturer_Apple;
// Get component // Get component
AudioComponent inputComponent = AudioComponentFindNext(nullptr, &desc); AudioComponent inputComponent = AudioComponentFindNext(null, &desc);
// Get audio units // Get audio units
status = AudioComponentInstanceNew(inputComponent, &m_private->audioUnit); status = AudioComponentInstanceNew(inputComponent, &m_private->audioUnit);

View File

@ -13,7 +13,7 @@
#include <audio/orchestra/api/Ds.hpp> #include <audio/orchestra/api/Ds.hpp>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Ds::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Ds::create() {
return ememory::SharedPtr<audio::orchestra::api::Ds>(new audio::orchestra::api::Ds()); return ememory::SharedPtr<audio::orchestra::api::Ds>(ETK_NEW(audio::orchestra::api::Ds));
} }
@ -23,11 +23,10 @@ ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Ds::create() {
// - Auto-call CoInitialize for DSOUND and ASIO platforms. // - Auto-call CoInitialize for DSOUND and ASIO platforms.
// Various revisions for RtAudio 4.0 by Gary Scavone, April 2007 // Various revisions for RtAudio 4.0 by Gary Scavone, April 2007
// Changed device query structure for RtAudio 4.0.7, January 2010 // Changed device query structure for RtAudio 4.0.7, January 2010
extern "C" {
#include <dsound.h> #include <dsound.h>
#include <cassert> #include <assert.h>
#include <algorithm> }
#if defined(__MINGW32__) #if defined(__MINGW32__)
// missing from latest mingw winapi // missing from latest mingw winapi
#define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */ #define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */
@ -59,7 +58,7 @@ class DsDevice {
public: public:
LPGUID id; LPGUID id;
bool input; bool input;
std::string name; etk::String name;
DsDevice() : DsDevice() :
id(0), id(0),
input(false) { input(false) {
@ -72,7 +71,7 @@ namespace audio {
namespace api { namespace api {
class DsPrivate { class DsPrivate {
public: public:
ememory::SharedPtr<std::thread> thread; ememory::SharedPtr<ethread::Thread> thread;
bool threadRunning; bool threadRunning;
uint32_t drainCounter; // Tracks callback counts when draining uint32_t drainCounter; // Tracks callback counts when draining
bool internalDrain; // Indicates if stop is initiated from callback or not. bool internalDrain; // Indicates if stop is initiated from callback or not.
@ -83,7 +82,7 @@ namespace audio {
DWORD dsBufferSize[2]; DWORD dsBufferSize[2];
DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by. DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by.
HANDLE condition; HANDLE condition;
std::vector<DsDevice> dsDevices; etk::Vector<DsDevice> dsDevices;
DsPrivate() : DsPrivate() :
threadRunning(false), threadRunning(false),
drainCounter(0), drainCounter(0),
@ -107,15 +106,15 @@ static const char* getErrorString(int32_t _code);
struct DsProbeData { struct DsProbeData {
bool isInput; bool isInput;
std::vector<DsDevice>* dsDevices; etk::Vector<DsDevice>* dsDevices;
}; };
audio::orchestra::api::Ds::Ds() : audio::orchestra::api::Ds::Ds() :
m_private(new audio::orchestra::api::DsPrivate()) { m_private(ETK_NEW(audio::orchestra::api::DsPrivate)) {
// Dsound will run both-threaded. If CoInitialize fails, then just // Dsound will run both-threaded. If CoInitialize fails, then just
// accept whatever the mainline chose for a threading model. // accept whatever the mainline chose for a threading model.
m_coInitialized = false; m_coInitialized = false;
HRESULT hr = CoInitialize(nullptr); HRESULT hr = CoInitialize(null);
if (!FAILED(hr)) { if (!FAILED(hr)) {
m_coInitialized = true; m_coInitialized = true;
} }
@ -132,13 +131,13 @@ audio::orchestra::api::Ds::~Ds() {
#include "tchar.h" #include "tchar.h"
static std::string convertTChar(LPCTSTR _name) { static etk::String convertTChar(LPCTSTR _name) {
#if defined(UNICODE) || defined(_UNICODE) #if defined(UNICODE) || defined(_UNICODE)
int32_t length = WideCharToMultiByte(CP_UTF8, 0, _name, -1, nullptr, 0, nullptr, nullptr); int32_t length = WideCharToMultiByte(CP_UTF8, 0, _name, -1, null, 0, null, null);
std::string s(length-1, '\0'); etk::String s(length-1, '\0');
WideCharToMultiByte(CP_UTF8, 0, _name, -1, &s[0], length, nullptr, nullptr); WideCharToMultiByte(CP_UTF8, 0, _name, -1, &s[0], length, null, null);
#else #else
std::string s(_name); etk::String s(_name);
#endif #endif
return s; return s;
} }
@ -148,13 +147,13 @@ static BOOL CALLBACK deviceQueryCallback(LPGUID _lpguid,
LPCTSTR _module, LPCTSTR _module,
LPVOID _lpContext) { LPVOID _lpContext) {
struct DsProbeData& probeInfo = *(struct DsProbeData*) _lpContext; struct DsProbeData& probeInfo = *(struct DsProbeData*) _lpContext;
std::vector<DsDevice>& dsDevices = *probeInfo.dsDevices; etk::Vector<DsDevice>& dsDevices = *probeInfo.dsDevices;
HRESULT hr; HRESULT hr;
bool validDevice = false; bool validDevice = false;
if (probeInfo.isInput == true) { if (probeInfo.isInput == true) {
DSCCAPS caps; DSCCAPS caps;
LPDIRECTSOUNDCAPTURE object; LPDIRECTSOUNDCAPTURE object;
hr = DirectSoundCaptureCreate(_lpguid, &object, nullptr); hr = DirectSoundCaptureCreate(_lpguid, &object, null);
if (hr != DS_OK) { if (hr != DS_OK) {
return TRUE; return TRUE;
} }
@ -169,7 +168,7 @@ static BOOL CALLBACK deviceQueryCallback(LPGUID _lpguid,
} else { } else {
DSCAPS caps; DSCAPS caps;
LPDIRECTSOUND object; LPDIRECTSOUND object;
hr = DirectSoundCreate(_lpguid, &object, nullptr); hr = DirectSoundCreate(_lpguid, &object, null);
if (hr != DS_OK) { if (hr != DS_OK) {
return TRUE; return TRUE;
} }
@ -187,16 +186,16 @@ static BOOL CALLBACK deviceQueryCallback(LPGUID _lpguid,
return TRUE; return TRUE;
} }
// If good device, then save its name and guid. // If good device, then save its name and guid.
std::string name = convertTChar(_description); etk::String name = convertTChar(_description);
//if (name == "Primary Sound Driver" || name == "Primary Sound Capture Driver") //if (name == "Primary Sound Driver" || name == "Primary Sound Capture Driver")
if (_lpguid == nullptr) { if (_lpguid == null) {
name = "Default Device"; name = "Default Device";
} }
DsDevice device; DsDevice device;
device.name = name; device.name = name;
device.input = probeInfo.isInput; device.input = probeInfo.isInput;
device.id = _lpguid; device.id = _lpguid;
dsDevices.push_back(device); dsDevices.pushBack(device);
return TRUE; return TRUE;
} }
@ -234,7 +233,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Ds::getDeviceInfo(uint32_t _
info.input = true; info.input = true;
LPDIRECTSOUND output; LPDIRECTSOUND output;
DSCAPS outCaps; DSCAPS outCaps;
result = DirectSoundCreate(m_private->dsDevices[_device].id, &output, nullptr); result = DirectSoundCreate(m_private->dsDevices[_device].id, &output, null);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": opening output device (" << m_private->dsDevices[_device].name << ")!"); ATA_ERROR(getErrorString(result) << ": opening output device (" << m_private->dsDevices[_device].name << ")!");
info.clear(); info.clear();
@ -250,24 +249,24 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Ds::getDeviceInfo(uint32_t _
} }
// Get output channel information. // Get output channel information.
if (outCaps.dwFlags & DSCAPS_PRIMARYSTEREO) { if (outCaps.dwFlags & DSCAPS_PRIMARYSTEREO) {
info.channels.push_back(audio::channel_unknow); info.channels.pushBack(audio::channel_unknow);
info.channels.push_back(audio::channel_unknow); info.channels.pushBack(audio::channel_unknow);
} else { } else {
info.channels.push_back(audio::channel_unknow); info.channels.pushBack(audio::channel_unknow);
} }
// Get sample rate information. // Get sample rate information.
for (auto &it : audio::orchestra::genericSampleRate()) { for (auto &it : audio::orchestra::genericSampleRate()) {
if ( it >= outCaps.dwMinSecondarySampleRate if ( it >= outCaps.dwMinSecondarySampleRate
&& it <= outCaps.dwMaxSecondarySampleRate) { && it <= outCaps.dwMaxSecondarySampleRate) {
info.sampleRates.push_back(it); info.sampleRates.pushBack(it);
} }
} }
// Get format information. // Get format information.
if (outCaps.dwFlags & DSCAPS_PRIMARY16BIT) { if (outCaps.dwFlags & DSCAPS_PRIMARY16BIT) {
info.nativeFormats.push_back(audio::format_int16); info.nativeFormats.pushBack(audio::format_int16);
} }
if (outCaps.dwFlags & DSCAPS_PRIMARY8BIT) { if (outCaps.dwFlags & DSCAPS_PRIMARY8BIT) {
info.nativeFormats.push_back(audio::format_int8); info.nativeFormats.pushBack(audio::format_int8);
} }
output->Release(); output->Release();
info.name = m_private->dsDevices[_device].name; info.name = m_private->dsDevices[_device].name;
@ -275,7 +274,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Ds::getDeviceInfo(uint32_t _
return info; return info;
} else { } else {
LPDIRECTSOUNDCAPTURE input; LPDIRECTSOUNDCAPTURE input;
result = DirectSoundCaptureCreate(m_private->dsDevices[_device].id, &input, nullptr); result = DirectSoundCaptureCreate(m_private->dsDevices[_device].id, &input, null);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": opening input device (" << m_private->dsDevices[_device].name << ")!"); ATA_ERROR(getErrorString(result) << ": opening input device (" << m_private->dsDevices[_device].name << ")!");
info.clear(); info.clear();
@ -292,67 +291,67 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Ds::getDeviceInfo(uint32_t _
} }
// Get input channel information. // Get input channel information.
for (int32_t iii=0; iii<inCaps.dwChannels; ++iii) { for (int32_t iii=0; iii<inCaps.dwChannels; ++iii) {
info.channels.push_back(audio::channel_unknow); info.channels.pushBack(audio::channel_unknow);
} }
// Get sample rate and format information. // Get sample rate and format information.
std::vector<uint32_t> rates; etk::Vector<uint32_t> rates;
if (inCaps.dwChannels >= 2) { if (inCaps.dwChannels >= 2) {
if ( (inCaps.dwFormats & WAVE_FORMAT_1S16) if ( (inCaps.dwFormats & WAVE_FORMAT_1S16)
|| (inCaps.dwFormats & WAVE_FORMAT_2S16) || (inCaps.dwFormats & WAVE_FORMAT_2S16)
|| (inCaps.dwFormats & WAVE_FORMAT_4S16) || (inCaps.dwFormats & WAVE_FORMAT_4S16)
|| (inCaps.dwFormats & WAVE_FORMAT_96S16) ) { || (inCaps.dwFormats & WAVE_FORMAT_96S16) ) {
info.nativeFormats.push_back(audio::format_int16); info.nativeFormats.pushBack(audio::format_int16);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_1S08) if ( (inCaps.dwFormats & WAVE_FORMAT_1S08)
|| (inCaps.dwFormats & WAVE_FORMAT_2S08) || (inCaps.dwFormats & WAVE_FORMAT_2S08)
|| (inCaps.dwFormats & WAVE_FORMAT_4S08) || (inCaps.dwFormats & WAVE_FORMAT_4S08)
|| (inCaps.dwFormats & WAVE_FORMAT_96S08) ) { || (inCaps.dwFormats & WAVE_FORMAT_96S08) ) {
info.nativeFormats.push_back(audio::format_int8); info.nativeFormats.pushBack(audio::format_int8);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_1S16) if ( (inCaps.dwFormats & WAVE_FORMAT_1S16)
|| (inCaps.dwFormats & WAVE_FORMAT_1S08) ){ || (inCaps.dwFormats & WAVE_FORMAT_1S08) ){
rates.push_back(11025); rates.pushBack(11025);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_2S16) if ( (inCaps.dwFormats & WAVE_FORMAT_2S16)
|| (inCaps.dwFormats & WAVE_FORMAT_2S08) ){ || (inCaps.dwFormats & WAVE_FORMAT_2S08) ){
rates.push_back(22050); rates.pushBack(22050);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_4S16) if ( (inCaps.dwFormats & WAVE_FORMAT_4S16)
|| (inCaps.dwFormats & WAVE_FORMAT_4S08) ){ || (inCaps.dwFormats & WAVE_FORMAT_4S08) ){
rates.push_back(44100); rates.pushBack(44100);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_96S16) if ( (inCaps.dwFormats & WAVE_FORMAT_96S16)
|| (inCaps.dwFormats & WAVE_FORMAT_96S08) ){ || (inCaps.dwFormats & WAVE_FORMAT_96S08) ){
rates.push_back(96000); rates.pushBack(96000);
} }
} else if (inCaps.dwChannels == 1) { } else if (inCaps.dwChannels == 1) {
if ( (inCaps.dwFormats & WAVE_FORMAT_1M16) if ( (inCaps.dwFormats & WAVE_FORMAT_1M16)
|| (inCaps.dwFormats & WAVE_FORMAT_2M16) || (inCaps.dwFormats & WAVE_FORMAT_2M16)
|| (inCaps.dwFormats & WAVE_FORMAT_4M16) || (inCaps.dwFormats & WAVE_FORMAT_4M16)
|| (inCaps.dwFormats & WAVE_FORMAT_96M16) ) { || (inCaps.dwFormats & WAVE_FORMAT_96M16) ) {
info.nativeFormats.push_back(audio::format_int16); info.nativeFormats.pushBack(audio::format_int16);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_1M08) if ( (inCaps.dwFormats & WAVE_FORMAT_1M08)
|| (inCaps.dwFormats & WAVE_FORMAT_2M08) || (inCaps.dwFormats & WAVE_FORMAT_2M08)
|| (inCaps.dwFormats & WAVE_FORMAT_4M08) || (inCaps.dwFormats & WAVE_FORMAT_4M08)
|| (inCaps.dwFormats & WAVE_FORMAT_96M08) ) { || (inCaps.dwFormats & WAVE_FORMAT_96M08) ) {
info.nativeFormats.push_back(audio::format_int8); info.nativeFormats.pushBack(audio::format_int8);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_1M16) if ( (inCaps.dwFormats & WAVE_FORMAT_1M16)
|| (inCaps.dwFormats & WAVE_FORMAT_1M08) ){ || (inCaps.dwFormats & WAVE_FORMAT_1M08) ){
rates.push_back(11025); rates.pushBack(11025);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_2M16) if ( (inCaps.dwFormats & WAVE_FORMAT_2M16)
|| (inCaps.dwFormats & WAVE_FORMAT_2M08) ){ || (inCaps.dwFormats & WAVE_FORMAT_2M08) ){
rates.push_back(22050); rates.pushBack(22050);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_4M16) if ( (inCaps.dwFormats & WAVE_FORMAT_4M16)
|| (inCaps.dwFormats & WAVE_FORMAT_4M08) ){ || (inCaps.dwFormats & WAVE_FORMAT_4M08) ){
rates.push_back(44100); rates.pushBack(44100);
} }
if ( (inCaps.dwFormats & WAVE_FORMAT_96M16) if ( (inCaps.dwFormats & WAVE_FORMAT_96M16)
|| (inCaps.dwFormats & WAVE_FORMAT_96M08) ){ || (inCaps.dwFormats & WAVE_FORMAT_96M08) ){
rates.push_back(96000); rates.pushBack(96000);
} }
} else { } else {
// technically, this would be an error // technically, this would be an error
@ -374,10 +373,10 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Ds::getDeviceInfo(uint32_t _
} }
} }
if (found == false) { if (found == false) {
info.sampleRates.push_back(rates[i]); info.sampleRates.pushBack(rates[i]);
} }
} }
std::sort(info.sampleRates.begin(), info.sampleRates.end()); info.sampleRates.sort(0, info.sampleRates.size(), [](const uint32_t& _left, const uint32_t& _right) { return _left < _right;});
// Copy name and return. // Copy name and return.
info.name = m_private->dsDevices[_device].name; info.name = m_private->dsDevices[_device].name;
info.isCorrect = true; info.isCorrect = true;
@ -453,7 +452,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
HRESULT result; HRESULT result;
if (_mode == audio::orchestra::mode_output) { if (_mode == audio::orchestra::mode_output) {
LPDIRECTSOUND output; LPDIRECTSOUND output;
result = DirectSoundCreate(m_private->dsDevices[_device].id, &output, nullptr); result = DirectSoundCreate(m_private->dsDevices[_device].id, &output, null);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": opening output device (" << m_private->dsDevices[_device].name << ")!"); ATA_ERROR(getErrorString(result) << ": opening output device (" << m_private->dsDevices[_device].name << ")!");
return false; return false;
@ -510,7 +509,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER; bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;
// Obtain the primary buffer // Obtain the primary buffer
LPDIRECTSOUNDBUFFER buffer; LPDIRECTSOUNDBUFFER buffer;
result = output->CreateSoundBuffer(&bufferDescription, &buffer, nullptr); result = output->CreateSoundBuffer(&bufferDescription, &buffer, null);
if (FAILED(result)) { if (FAILED(result)) {
output->Release(); output->Release();
ATA_ERROR(getErrorString(result) << ": accessing primary buffer (" << m_private->dsDevices[_device].name << ")!"); ATA_ERROR(getErrorString(result) << ": accessing primary buffer (" << m_private->dsDevices[_device].name << ")!");
@ -534,13 +533,13 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
bufferDescription.lpwfxFormat = &waveFormat; bufferDescription.lpwfxFormat = &waveFormat;
// Try to create the secondary DS buffer. If that doesn't work, // Try to create the secondary DS buffer. If that doesn't work,
// try to use software mixing. Otherwise, there's a problem. // try to use software mixing. Otherwise, there's a problem.
result = output->CreateSoundBuffer(&bufferDescription, &buffer, nullptr); result = output->CreateSoundBuffer(&bufferDescription, &buffer, null);
if (FAILED(result)) { if (FAILED(result)) {
bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS
| DSBCAPS_GLOBALFOCUS | DSBCAPS_GLOBALFOCUS
| DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCSOFTWARE); // Force software mixing | DSBCAPS_LOCSOFTWARE); // Force software mixing
result = output->CreateSoundBuffer(&bufferDescription, &buffer, nullptr); result = output->CreateSoundBuffer(&bufferDescription, &buffer, null);
if (FAILED(result)) { if (FAILED(result)) {
output->Release(); output->Release();
ATA_ERROR(getErrorString(result) << ": creating secondary buffer (" << m_private->dsDevices[_device].name << ")!"); ATA_ERROR(getErrorString(result) << ": creating secondary buffer (" << m_private->dsDevices[_device].name << ")!");
@ -561,7 +560,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
// Lock the DS buffer // Lock the DS buffer
LPVOID audioPtr; LPVOID audioPtr;
DWORD dataLen; DWORD dataLen;
result = buffer->Lock(0, dsBufferSize, &audioPtr, &dataLen, nullptr, nullptr, 0); result = buffer->Lock(0, dsBufferSize, &audioPtr, &dataLen, null, null, 0);
if (FAILED(result)) { if (FAILED(result)) {
output->Release(); output->Release();
buffer->Release(); buffer->Release();
@ -571,7 +570,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
// Zero the DS buffer // Zero the DS buffer
ZeroMemory(audioPtr, dataLen); ZeroMemory(audioPtr, dataLen);
// Unlock the DS buffer // Unlock the DS buffer
result = buffer->Unlock(audioPtr, dataLen, nullptr, 0); result = buffer->Unlock(audioPtr, dataLen, null, 0);
if (FAILED(result)) { if (FAILED(result)) {
output->Release(); output->Release();
buffer->Release(); buffer->Release();
@ -583,7 +582,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
} }
if (_mode == audio::orchestra::mode_input) { if (_mode == audio::orchestra::mode_input) {
LPDIRECTSOUNDCAPTURE input; LPDIRECTSOUNDCAPTURE input;
result = DirectSoundCaptureCreate(m_private->dsDevices[_device].id, &input, nullptr); result = DirectSoundCaptureCreate(m_private->dsDevices[_device].id, &input, null);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": opening input device (" << m_private->dsDevices[_device].name << ")!"); ATA_ERROR(getErrorString(result) << ": opening input device (" << m_private->dsDevices[_device].name << ")!");
return false; return false;
@ -643,7 +642,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
bufferDescription.lpwfxFormat = &waveFormat; bufferDescription.lpwfxFormat = &waveFormat;
// Create the capture buffer. // Create the capture buffer.
LPDIRECTSOUNDCAPTUREBUFFER buffer; LPDIRECTSOUNDCAPTUREBUFFER buffer;
result = input->CreateCaptureBuffer(&bufferDescription, &buffer, nullptr); result = input->CreateCaptureBuffer(&bufferDescription, &buffer, null);
if (FAILED(result)) { if (FAILED(result)) {
input->Release(); input->Release();
ATA_ERROR(getErrorString(result) << ": creating input buffer (" << m_private->dsDevices[_device].name << ")!"); ATA_ERROR(getErrorString(result) << ": creating input buffer (" << m_private->dsDevices[_device].name << ")!");
@ -667,7 +666,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
// Lock the capture buffer // Lock the capture buffer
LPVOID audioPtr; LPVOID audioPtr;
DWORD dataLen; DWORD dataLen;
result = buffer->Lock(0, dsBufferSize, &audioPtr, &dataLen, nullptr, nullptr, 0); result = buffer->Lock(0, dsBufferSize, &audioPtr, &dataLen, null, null, 0);
if (FAILED(result)) { if (FAILED(result)) {
input->Release(); input->Release();
buffer->Release(); buffer->Release();
@ -677,7 +676,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
// Zero the buffer // Zero the buffer
ZeroMemory(audioPtr, dataLen); ZeroMemory(audioPtr, dataLen);
// Unlock the buffer // Unlock the buffer
result = buffer->Unlock(audioPtr, dataLen, nullptr, 0); result = buffer->Unlock(audioPtr, dataLen, null, 0);
if (FAILED(result)) { if (FAILED(result)) {
input->Release(); input->Release();
buffer->Release(); buffer->Release();
@ -729,17 +728,17 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
free(m_deviceBuffer); free(m_deviceBuffer);
} }
m_deviceBuffer = (char *) calloc(bufferBytes, 1); m_deviceBuffer = (char *) calloc(bufferBytes, 1);
if (m_deviceBuffer == nullptr) { if (m_deviceBuffer == null) {
ATA_ERROR("error allocating device buffer memory."); ATA_ERROR("error allocating device buffer memory.");
goto error; goto error;
} }
} }
} }
// Create a manual-reset event. // Create a manual-reset event.
m_private->condition = CreateEvent(nullptr, // no security m_private->condition = CreateEvent(null, // no security
TRUE, // manual-reset TRUE, // manual-reset
FALSE, // non-signaled initially FALSE, // non-signaled initially
nullptr); // unnamed null); // unnamed
m_private->id[modeToIdTable(_mode)] = ohandle; m_private->id[modeToIdTable(_mode)] = ohandle;
m_private->buffer[modeToIdTable(_mode)] = bhandle; m_private->buffer[modeToIdTable(_mode)] = bhandle;
m_private->dsBufferSize[modeToIdTable(_mode)] = dsBufferSize; m_private->dsBufferSize[modeToIdTable(_mode)] = dsBufferSize;
@ -762,9 +761,9 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
// Setup the callback thread. // Setup the callback thread.
if (m_private->threadRunning == false) { if (m_private->threadRunning == false) {
m_private->threadRunning = true; m_private->threadRunning = true;
ememory::SharedPtr<std::thread> tmpThread(new std::thread(&audio::orchestra::api::Ds::dsCallbackEvent, this)); ememory::SharedPtr<ethread::Thread> tmpThread(ETK_NEW(ethread::Thread, [=](){audio::orchestra::api::Ds::dsCallbackEvent();});
m_private->thread = std::move(tmpThread); m_private->thread = etk::move(tmpThread);
if (m_private->thread == nullptr) { if (m_private->thread == null) {
ATA_ERROR("error creating callback thread!"); ATA_ERROR("error creating callback thread!");
goto error; goto error;
} }
@ -774,7 +773,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
return true; return true;
error: error:
if (m_private->buffer[0]) { if (m_private->buffer[0]) {
// the object pointer can be nullptr and valid // the object pointer can be null and valid
LPDIRECTSOUND object = (LPDIRECTSOUND) m_private->id[0]; LPDIRECTSOUND object = (LPDIRECTSOUND) m_private->id[0];
LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) m_private->buffer[0]; LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) m_private->buffer[0];
if (buffer) { if (buffer) {
@ -785,7 +784,7 @@ error:
if (m_private->buffer[1]) { if (m_private->buffer[1]) {
LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) m_private->id[1]; LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) m_private->id[1];
LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) m_private->buffer[1]; LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) m_private->buffer[1];
if (buffer != nullptr) { if (buffer != null) {
buffer->Release(); buffer->Release();
} }
} }
@ -808,11 +807,11 @@ enum audio::orchestra::error audio::orchestra::api::Ds::closeStream() {
} }
// Stop the callback thread. // Stop the callback thread.
m_private->threadRunning = false; m_private->threadRunning = false;
if (m_private->thread != nullptr) { if (m_private->thread != null) {
m_private->thread->join(); m_private->thread->join();
m_private->thread = nullptr; m_private->thread = null;
} }
if (m_private->buffer[0]) { // the object pointer can be nullptr and valid if (m_private->buffer[0]) { // the object pointer can be null and valid
LPDIRECTSOUND object = (LPDIRECTSOUND) m_private->id[0]; LPDIRECTSOUND object = (LPDIRECTSOUND) m_private->id[0];
LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) m_private->buffer[0]; LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) m_private->buffer[0];
if (buffer) { if (buffer) {
@ -919,7 +918,7 @@ enum audio::orchestra::error audio::orchestra::api::Ds::stopStream() {
} }
// Lock the buffer and clear it so that if we start to play again, // Lock the buffer and clear it so that if we start to play again,
// we won't have old data playing. // we won't have old data playing.
result = buffer->Lock(0, m_private->dsBufferSize[0], &audioPtr, &dataLen, nullptr, nullptr, 0); result = buffer->Lock(0, m_private->dsBufferSize[0], &audioPtr, &dataLen, null, null, 0);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": locking output buffer!"); ATA_ERROR(getErrorString(result) << ": locking output buffer!");
goto unlock; goto unlock;
@ -927,7 +926,7 @@ enum audio::orchestra::error audio::orchestra::api::Ds::stopStream() {
// Zero the DS buffer // Zero the DS buffer
ZeroMemory(audioPtr, dataLen); ZeroMemory(audioPtr, dataLen);
// Unlock the DS buffer // Unlock the DS buffer
result = buffer->Unlock(audioPtr, dataLen, nullptr, 0); result = buffer->Unlock(audioPtr, dataLen, null, 0);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": unlocking output buffer!"); ATA_ERROR(getErrorString(result) << ": unlocking output buffer!");
goto unlock; goto unlock;
@ -938,7 +937,7 @@ enum audio::orchestra::error audio::orchestra::api::Ds::stopStream() {
if ( m_mode == audio::orchestra::mode_input if ( m_mode == audio::orchestra::mode_input
|| m_mode == audio::orchestra::mode_duplex) { || m_mode == audio::orchestra::mode_duplex) {
LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) m_private->buffer[1]; LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) m_private->buffer[1];
audioPtr = nullptr; audioPtr = null;
dataLen = 0; dataLen = 0;
m_state = audio::orchestra::state::stopped; m_state = audio::orchestra::state::stopped;
result = buffer->Stop(); result = buffer->Stop();
@ -948,7 +947,7 @@ enum audio::orchestra::error audio::orchestra::api::Ds::stopStream() {
} }
// Lock the buffer and clear it so that if we start to play again, // Lock the buffer and clear it so that if we start to play again,
// we won't have old data playing. // we won't have old data playing.
result = buffer->Lock(0, m_private->dsBufferSize[1], &audioPtr, &dataLen, nullptr, nullptr, 0); result = buffer->Lock(0, m_private->dsBufferSize[1], &audioPtr, &dataLen, null, null, 0);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": locking input buffer!"); ATA_ERROR(getErrorString(result) << ": locking input buffer!");
goto unlock; goto unlock;
@ -956,7 +955,7 @@ enum audio::orchestra::error audio::orchestra::api::Ds::stopStream() {
// Zero the DS buffer // Zero the DS buffer
ZeroMemory(audioPtr, dataLen); ZeroMemory(audioPtr, dataLen);
// Unlock the DS buffer // Unlock the DS buffer
result = buffer->Unlock(audioPtr, dataLen, nullptr, 0); result = buffer->Unlock(audioPtr, dataLen, null, 0);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": unlocking input buffer!"); ATA_ERROR(getErrorString(result) << ": unlocking input buffer!");
goto unlock; goto unlock;
@ -1009,15 +1008,15 @@ void audio::orchestra::api::Ds::callbackEvent() {
// draining stream. // draining stream.
if (m_private->drainCounter == 0) { if (m_private->drainCounter == 0) {
audio::Time streamTime = getStreamTime(); audio::Time streamTime = getStreamTime();
std::vector<audio::orchestra::status> status; etk::Vector<audio::orchestra::status> status;
if ( m_mode != audio::orchestra::mode_input if ( m_mode != audio::orchestra::mode_input
&& m_private->xrun[0] == true) { && m_private->xrun[0] == true) {
status.push_back(audio::orchestra::status::underflow); status.pushBack(audio::orchestra::status::underflow);
m_private->xrun[0] = false; m_private->xrun[0] = false;
} }
if ( m_mode != audio::orchestra::mode_output if ( m_mode != audio::orchestra::mode_output
&& m_private->xrun[1] == true) { && m_private->xrun[1] == true) {
status.push_back(audio::orchestra::status::overflow); status.pushBack(audio::orchestra::status::overflow);
m_private->xrun[1] = false; m_private->xrun[1] = false;
} }
int32_t cbReturnValue = m_callback(&m_userBuffer[1][0], int32_t cbReturnValue = m_callback(&m_userBuffer[1][0],
@ -1040,8 +1039,8 @@ void audio::orchestra::api::Ds::callbackEvent() {
DWORD currentWritePointer, safeWritePointer; DWORD currentWritePointer, safeWritePointer;
DWORD currentReadPointer, safeReadPointer; DWORD currentReadPointer, safeReadPointer;
UINT nextWritePointer; UINT nextWritePointer;
LPVOID buffer1 = nullptr; LPVOID buffer1 = null;
LPVOID buffer2 = nullptr; LPVOID buffer2 = null;
DWORD bufferSize1 = 0; DWORD bufferSize1 = 0;
DWORD bufferSize2 = 0; DWORD bufferSize2 = 0;
char *buffer; char *buffer;
@ -1064,23 +1063,23 @@ void audio::orchestra::api::Ds::callbackEvent() {
LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) m_private->buffer[0]; LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) m_private->buffer[0];
LPDIRECTSOUNDCAPTUREBUFFER dsCaptureBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) m_private->buffer[1]; LPDIRECTSOUNDCAPTUREBUFFER dsCaptureBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) m_private->buffer[1];
DWORD startSafeWritePointer, startSafeReadPointer; DWORD startSafeWritePointer, startSafeReadPointer;
result = dsWriteBuffer->GetCurrentPosition(nullptr, &startSafeWritePointer); result = dsWriteBuffer->GetCurrentPosition(null, &startSafeWritePointer);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": getting current write position!"); ATA_ERROR(getErrorString(result) << ": getting current write position!");
return; return;
} }
result = dsCaptureBuffer->GetCurrentPosition(nullptr, &startSafeReadPointer); result = dsCaptureBuffer->GetCurrentPosition(null, &startSafeReadPointer);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": getting current read position!"); ATA_ERROR(getErrorString(result) << ": getting current read position!");
return; return;
} }
while (true) { while (true) {
result = dsWriteBuffer->GetCurrentPosition(nullptr, &safeWritePointer); result = dsWriteBuffer->GetCurrentPosition(null, &safeWritePointer);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": getting current write position!"); ATA_ERROR(getErrorString(result) << ": getting current write position!");
return; return;
} }
result = dsCaptureBuffer->GetCurrentPosition(nullptr, &safeReadPointer); result = dsCaptureBuffer->GetCurrentPosition(null, &safeReadPointer);
if (FAILED(result)) { if (FAILED(result)) {
ATA_ERROR(getErrorString(result) << ": getting current read position!"); ATA_ERROR(getErrorString(result) << ": getting current read position!");
return; return;
@ -1154,7 +1153,7 @@ void audio::orchestra::api::Ds::callbackEvent() {
// safeWritePointer and leadPointer. If leadPointer is not // safeWritePointer and leadPointer. If leadPointer is not
// beyond the next endWrite position, wait until it is. // beyond the next endWrite position, wait until it is.
leadPointer = safeWritePointer + m_private->dsPointerLeadTime[0]; leadPointer = safeWritePointer + m_private->dsPointerLeadTime[0];
//std::cout << "safeWritePointer = " << safeWritePointer << ", leadPointer = " << leadPointer << ", nextWritePointer = " << nextWritePointer << std::endl; //ATA_DEBUG("safeWritePointer = " << safeWritePointer << ", leadPointer = " << leadPointer << ", nextWritePointer = " << nextWritePointer);
if (leadPointer > dsBufferSize) { if (leadPointer > dsBufferSize) {
leadPointer -= dsBufferSize; leadPointer -= dsBufferSize;
} }
@ -1201,7 +1200,7 @@ void audio::orchestra::api::Ds::callbackEvent() {
} }
// Copy our buffer into the DS buffer // Copy our buffer into the DS buffer
CopyMemory(buffer1, buffer, bufferSize1); CopyMemory(buffer1, buffer, bufferSize1);
if (buffer2 != nullptr) { if (buffer2 != null) {
CopyMemory(buffer2, buffer+bufferSize1, bufferSize2); CopyMemory(buffer2, buffer+bufferSize1, bufferSize2);
} }
// Update our buffer offset and unlock sound buffer // Update our buffer offset and unlock sound buffer
@ -1319,12 +1318,12 @@ void audio::orchestra::api::Ds::callbackEvent() {
if (m_duplexPrerollBytes <= 0) { if (m_duplexPrerollBytes <= 0) {
// Copy our buffer into the DS buffer // Copy our buffer into the DS buffer
CopyMemory(buffer, buffer1, bufferSize1); CopyMemory(buffer, buffer1, bufferSize1);
if (buffer2 != nullptr) { if (buffer2 != null) {
CopyMemory(buffer+bufferSize1, buffer2, bufferSize2); CopyMemory(buffer+bufferSize1, buffer2, bufferSize2);
} }
} else { } else {
memset(buffer, 0, bufferSize1); memset(buffer, 0, bufferSize1);
if (buffer2 != nullptr) { if (buffer2 != null) {
memset(buffer + bufferSize1, 0, bufferSize2); memset(buffer + bufferSize1, 0, bufferSize2);
} }
m_duplexPrerollBytes -= bufferSize1 + bufferSize2; m_duplexPrerollBytes -= bufferSize1 + bufferSize2;

View File

@ -17,7 +17,7 @@ namespace audio {
public: public:
Ds(); Ds();
virtual ~Ds(); virtual ~Ds();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typeDs; return audio::orchestra::typeDs;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();

View File

@ -10,7 +10,7 @@
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Dummy::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Dummy::create() {
return ememory::SharedPtr<audio::orchestra::api::Dummy>(new audio::orchestra::api::Dummy()); return ememory::SharedPtr<audio::orchestra::api::Dummy>(ETK_NEW(audio::orchestra::api::Dummy));
} }

View File

@ -18,7 +18,7 @@ namespace audio {
static ememory::SharedPtr<audio::orchestra::Api> create(); static ememory::SharedPtr<audio::orchestra::Api> create();
public: public:
Dummy(); Dummy();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typeDummy; return audio::orchestra::typeDummy;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();

View File

@ -7,17 +7,17 @@
// must run before : // must run before :
#if defined(ORCHESTRA_BUILD_JACK) #if defined(ORCHESTRA_BUILD_JACK)
extern "C" {
#include <climits> #include <limits.h>
#include <iostream> #include <string.h>
}
#include <audio/orchestra/Interface.hpp> #include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <cstring>
#include <ethread/tools.hpp> #include <ethread/tools.hpp>
#include <audio/orchestra/api/Jack.hpp> #include <audio/orchestra/api/Jack.hpp>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Jack::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Jack::create() {
return ememory::SharedPtr<audio::orchestra::api::Jack>(new audio::orchestra::api::Jack()); return ememory::SharedPtr<audio::orchestra::api::Jack>(ETK_NEW(audio::orchestra::api::Jack));
} }
@ -52,9 +52,9 @@ ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Jack::create()
// stream cannot be opened. // stream cannot be opened.
#include <jack/jack.h> #include <jack/jack.h>
extern "C" {
#include <cstdio> #include <stdio.h>
}
namespace audio { namespace audio {
namespace orchestra { namespace orchestra {
@ -63,9 +63,9 @@ namespace audio {
public: public:
jack_client_t *client; jack_client_t *client;
jack_port_t **ports[2]; jack_port_t **ports[2];
std::string deviceName[2]; etk::String deviceName[2];
bool xrun[2]; bool xrun[2];
std::condition_variable condition; ethread::Semaphore m_semaphore;
int32_t drainCounter; // Tracks callback counts when draining int32_t drainCounter; // Tracks callback counts when draining
bool internalDrain; // Indicates if stop is initiated from callback or not. bool internalDrain; // Indicates if stop is initiated from callback or not.
@ -84,7 +84,7 @@ namespace audio {
} }
audio::orchestra::api::Jack::Jack() : audio::orchestra::api::Jack::Jack() :
m_private(new audio::orchestra::api::JackPrivate()) { m_private(ETK_NEW(audio::orchestra::api::JackPrivate)) {
// Nothing to do here. // Nothing to do here.
} }
@ -97,23 +97,23 @@ audio::orchestra::api::Jack::~Jack() {
uint32_t audio::orchestra::api::Jack::getDeviceCount() { uint32_t audio::orchestra::api::Jack::getDeviceCount() {
// See if we can become a jack client. // See if we can become a jack client.
jack_options_t options = (jack_options_t) (JackNoStartServer); //JackNullOption; jack_options_t options = (jack_options_t) (JackNoStartServer); //JackNullOption;
jack_status_t *status = nullptr; jack_status_t *status = null;
jack_client_t *client = jack_client_open("orchestraJackCount", options, status); jack_client_t *client = jack_client_open("orchestraJackCount", options, status);
if (client == nullptr) { if (client == null) {
return 0; return 0;
} }
const char **ports; const char **ports;
std::string port, previousPort; etk::String port, previousPort;
uint32_t nChannels = 0, nDevices = 0; uint32_t nChannels = 0, nDevices = 0;
ports = jack_get_ports(client, nullptr, nullptr, 0); ports = jack_get_ports(client, null, null, 0);
if (ports) { if (ports) {
// Parse the port names up to the first colon (:). // Parse the port names up to the first colon (:).
size_t iColon = 0; size_t iColon = 0;
do { do {
port = (char *) ports[ nChannels ]; port = (char *) ports[ nChannels ];
iColon = port.find(":"); iColon = port.find(":");
if (iColon != std::string::npos) { if (iColon != etk::String::npos) {
port = port.substr(0, iColon + 1); port = port.extract(0, iColon + 1);
if (port != previousPort) { if (port != previousPort) {
nDevices++; nDevices++;
previousPort = port; previousPort = port;
@ -121,6 +121,7 @@ uint32_t audio::orchestra::api::Jack::getDeviceCount() {
} }
} while (ports[++nChannels]); } while (ports[++nChannels]);
free(ports); free(ports);
ports = null;
} }
jack_client_close(client); jack_client_close(client);
return nDevices*2; return nDevices*2;
@ -129,18 +130,18 @@ uint32_t audio::orchestra::api::Jack::getDeviceCount() {
audio::orchestra::DeviceInfo audio::orchestra::api::Jack::getDeviceInfo(uint32_t _device) { audio::orchestra::DeviceInfo audio::orchestra::api::Jack::getDeviceInfo(uint32_t _device) {
audio::orchestra::DeviceInfo info; audio::orchestra::DeviceInfo info;
jack_options_t options = (jack_options_t) (JackNoStartServer); //JackNullOption jack_options_t options = (jack_options_t) (JackNoStartServer); //JackNullOption
jack_status_t *status = nullptr; jack_status_t *status = null;
jack_client_t *client = jack_client_open("orchestraJackInfo", options, status); jack_client_t *client = jack_client_open("orchestraJackInfo", options, status);
if (client == nullptr) { if (client == null) {
ATA_ERROR("Jack server not found or connection error!"); ATA_ERROR("Jack server not found or connection error!");
// TODO : audio::orchestra::error_warning; // TODO : audio::orchestra::error_warning;
info.clear(); info.clear();
return info; return info;
} }
const char **ports; const char **ports;
std::string port, previousPort; etk::String port, previousPort;
uint32_t nPorts = 0, nDevices = 0; uint32_t nPorts = 0, nDevices = 0;
ports = jack_get_ports(client, nullptr, nullptr, 0); ports = jack_get_ports(client, null, null, 0);
int32_t deviceID = _device/2; int32_t deviceID = _device/2;
info.input = _device%2==0?true:false; // note that jack sens are inverted info.input = _device%2==0?true:false; // note that jack sens are inverted
if (ports) { if (ports) {
@ -149,8 +150,8 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Jack::getDeviceInfo(uint32_t
do { do {
port = (char *) ports[nPorts]; port = (char *) ports[nPorts];
iColon = port.find(":"); iColon = port.find(":");
if (iColon != std::string::npos) { if (iColon != etk::String::npos) {
port = port.substr(0, iColon); port = port.extract(0, iColon);
if (port != previousPort) { if (port != previousPort) {
if (nDevices == deviceID) { if (nDevices == deviceID) {
info.name = port; info.name = port;
@ -170,25 +171,25 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Jack::getDeviceInfo(uint32_t
} }
// Get the current jack server sample rate. // Get the current jack server sample rate.
info.sampleRates.clear(); info.sampleRates.clear();
info.sampleRates.push_back(jack_get_sample_rate(client)); info.sampleRates.pushBack(jack_get_sample_rate(client));
if (info.input == true) { if (info.input == true) {
ports = jack_get_ports(client, info.name.c_str(), nullptr, JackPortIsOutput); ports = jack_get_ports(client, info.name.c_str(), null, JackPortIsOutput);
if (ports) { if (ports) {
int32_t iii=0; int32_t iii=0;
while (ports[iii]) { while (ports[iii]) {
ATA_ERROR(" ploppp='" << ports[iii] << "'"); ATA_ERROR(" ploppp='" << ports[iii] << "'");
info.channels.push_back(audio::channel_unknow); info.channels.pushBack(audio::channel_unknow);
iii++; iii++;
} }
free(ports); free(ports);
} }
} else { } else {
ports = jack_get_ports(client, info.name.c_str(), nullptr, JackPortIsInput); ports = jack_get_ports(client, info.name.c_str(), null, JackPortIsInput);
if (ports) { if (ports) {
int32_t iii=0; int32_t iii=0;
while (ports[iii]) { while (ports[iii]) {
ATA_ERROR(" ploppp='" << ports[iii] << "'"); ATA_ERROR(" ploppp='" << ports[iii] << "'");
info.channels.push_back(audio::channel_unknow); info.channels.pushBack(audio::channel_unknow);
iii++; iii++;
} }
free(ports); free(ports);
@ -202,7 +203,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Jack::getDeviceInfo(uint32_t
return info; return info;
} }
// Jack always uses 32-bit floats. // Jack always uses 32-bit floats.
info.nativeFormats.push_back(audio::format_float); info.nativeFormats.pushBack(audio::format_float);
// Jack doesn't provide default devices so we'll use the first available one. // Jack doesn't provide default devices so we'll use the first available one.
if (deviceID == 0) { if (deviceID == 0) {
info.isDefault = true; info.isDefault = true;
@ -223,15 +224,6 @@ int32_t audio::orchestra::api::Jack::jackCallbackHandler(jack_nframes_t _nframes
return 0; return 0;
} }
// This function will be called by a spawned thread when the Jack
// server signals that it is shutting down. It is necessary to handle
// it this way because the jackShutdown() function must return before
// the jack_deactivate() function (in closeStream()) will return.
void audio::orchestra::api::Jack::jackCloseStream(void* _userData) {
ethread::setName("Jack_closeStream");
audio::orchestra::api::Jack* myClass = reinterpret_cast<audio::orchestra::api::Jack*>(_userData);
myClass->closeStream();
}
void audio::orchestra::api::Jack::jackShutdown(void* _userData) { void audio::orchestra::api::Jack::jackShutdown(void* _userData) {
audio::orchestra::api::Jack* myClass = reinterpret_cast<audio::orchestra::api::Jack*>(_userData); audio::orchestra::api::Jack* myClass = reinterpret_cast<audio::orchestra::api::Jack*>(_userData);
@ -243,7 +235,7 @@ void audio::orchestra::api::Jack::jackShutdown(void* _userData) {
if (myClass->isStreamRunning() == false) { if (myClass->isStreamRunning() == false) {
return; return;
} }
new std::thread(&audio::orchestra::api::Jack::jackCloseStream, _userData); ETK_NEW(ethread::Thread, [=](){myClass->closeStream();});
ATA_ERROR("The Jack server is shutting down this client ... stream stopped and closed!!"); ATA_ERROR("The Jack server is shutting down this client ... stream stopped and closed!!");
} }
@ -272,8 +264,8 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
|| ( _mode == audio::orchestra::mode_input || ( _mode == audio::orchestra::mode_input
&& m_mode != audio::orchestra::mode_output)) { && m_mode != audio::orchestra::mode_output)) {
jack_options_t jackoptions = (jack_options_t) (JackNoStartServer); //JackNullOption; jack_options_t jackoptions = (jack_options_t) (JackNoStartServer); //JackNullOption;
jack_status_t *status = nullptr; jack_status_t *status = null;
if (!_options.streamName.empty()) { if (_options.streamName.size() != 0) {
client = jack_client_open(_options.streamName.c_str(), jackoptions, status); client = jack_client_open(_options.streamName.c_str(), jackoptions, status);
} else { } else {
client = jack_client_open("orchestraJack", jackoptions, status); client = jack_client_open("orchestraJack", jackoptions, status);
@ -287,19 +279,19 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
client = m_private->client; client = m_private->client;
} }
const char **ports; const char **ports;
std::string port, previousPort, deviceName; etk::String port, previousPort, deviceName;
uint32_t nPorts = 0, nDevices = 0; uint32_t nPorts = 0, nDevices = 0;
int32_t deviceID = _device/2; int32_t deviceID = _device/2;
bool isInput = _device%2==0?true:false; bool isInput = _device%2==0?true:false;
ports = jack_get_ports(client, nullptr, nullptr, 0); ports = jack_get_ports(client, null, null, 0);
if (ports) { if (ports) {
// Parse the port names up to the first colon (:). // Parse the port names up to the first colon (:).
size_t iColon = 0; size_t iColon = 0;
do { do {
port = (char *) ports[ nPorts ]; port = (char *) ports[ nPorts ];
iColon = port.find(":"); iColon = port.find(":");
if (iColon != std::string::npos) { if (iColon != etk::String::npos) {
port = port.substr(0, iColon); port = port.extract(0, iColon);
if (port != previousPort) { if (port != previousPort) {
if (nDevices == deviceID) { if (nDevices == deviceID) {
deviceName = port; deviceName = port;
@ -322,7 +314,7 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
if (_mode == audio::orchestra::mode_input) { if (_mode == audio::orchestra::mode_input) {
flag = JackPortIsOutput; flag = JackPortIsOutput;
} }
ports = jack_get_ports(client, deviceName.c_str(), nullptr, flag); ports = jack_get_ports(client, deviceName.c_str(), null, flag);
if (ports) { if (ports) {
while (ports[ nChannels ]) { while (ports[ nChannels ]) {
nChannels++; nChannels++;
@ -343,7 +335,7 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
} }
m_sampleRate = jackRate; m_sampleRate = jackRate;
// Get the latency of the JACK port. // Get the latency of the JACK port.
ports = jack_get_ports(client, deviceName.c_str(), nullptr, flag); ports = jack_get_ports(client, deviceName.c_str(), null, flag);
if (ports[ _firstChannel ]) { if (ports[ _firstChannel ]) {
// Added by Ge Wang // Added by Ge Wang
jack_latency_callback_mode_t cbmode = (_mode == audio::orchestra::mode_input ? JackCaptureLatency : JackPlaybackLatency); jack_latency_callback_mode_t cbmode = (_mode == audio::orchestra::mode_input ? JackCaptureLatency : JackPlaybackLatency);
@ -409,7 +401,7 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
bufferBytes *= *_bufferSize; bufferBytes *= *_bufferSize;
if (m_deviceBuffer) free(m_deviceBuffer); if (m_deviceBuffer) free(m_deviceBuffer);
m_deviceBuffer = (char *) calloc(bufferBytes, 1); m_deviceBuffer = (char *) calloc(bufferBytes, 1);
if (m_deviceBuffer == nullptr) { if (m_deviceBuffer == null) {
ATA_ERROR("error allocating device buffer memory."); ATA_ERROR("error allocating device buffer memory.");
goto error; goto error;
} }
@ -417,7 +409,7 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
} }
// Allocate memory for the Jack ports (channels) identifiers. // Allocate memory for the Jack ports (channels) identifiers.
m_private->ports[modeToIdTable(_mode)] = (jack_port_t **) malloc (sizeof (jack_port_t *) * _channels); m_private->ports[modeToIdTable(_mode)] = (jack_port_t **) malloc (sizeof (jack_port_t *) * _channels);
if (m_private->ports[modeToIdTable(_mode)] == nullptr) { if (m_private->ports[modeToIdTable(_mode)] == null) {
ATA_ERROR("error allocating port memory."); ATA_ERROR("error allocating port memory.");
goto error; goto error;
} }
@ -464,20 +456,20 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
return true; return true;
error: error:
jack_client_close(m_private->client); jack_client_close(m_private->client);
if (m_private->ports[0] != nullptr) { if (m_private->ports[0] != null) {
free(m_private->ports[0]); free(m_private->ports[0]);
m_private->ports[0] = nullptr; m_private->ports[0] = null;
} }
if (m_private->ports[1] != nullptr) { if (m_private->ports[1] != null) {
free(m_private->ports[1]); free(m_private->ports[1]);
m_private->ports[1] = nullptr; m_private->ports[1] = null;
} }
for (int32_t iii=0; iii<2; ++iii) { for (int32_t iii=0; iii<2; ++iii) {
m_userBuffer[iii].clear(); m_userBuffer[iii].clear();
} }
if (m_deviceBuffer) { if (m_deviceBuffer) {
free(m_deviceBuffer); free(m_deviceBuffer);
m_deviceBuffer = nullptr; m_deviceBuffer = null;
} }
return false; return false;
} }
@ -487,26 +479,26 @@ enum audio::orchestra::error audio::orchestra::api::Jack::closeStream() {
ATA_ERROR("no open stream to close!"); ATA_ERROR("no open stream to close!");
return audio::orchestra::error_warning; return audio::orchestra::error_warning;
} }
if (m_private != nullptr) { if (m_private != null) {
if (m_state == audio::orchestra::state::running) { if (m_state == audio::orchestra::state::running) {
jack_deactivate(m_private->client); jack_deactivate(m_private->client);
} }
jack_client_close(m_private->client); jack_client_close(m_private->client);
} }
if (m_private->ports[0] != nullptr) { if (m_private->ports[0] != null) {
free(m_private->ports[0]); free(m_private->ports[0]);
m_private->ports[0] = nullptr; m_private->ports[0] = null;
} }
if (m_private->ports[1] != nullptr) { if (m_private->ports[1] != null) {
free(m_private->ports[1]); free(m_private->ports[1]);
m_private->ports[1] = nullptr; m_private->ports[1] = null;
} }
for (int32_t i=0; i<2; i++) { for (int32_t i=0; i<2; i++) {
m_userBuffer[i].clear(); m_userBuffer[i].clear();
} }
if (m_deviceBuffer) { if (m_deviceBuffer) {
free(m_deviceBuffer); free(m_deviceBuffer);
m_deviceBuffer = nullptr; m_deviceBuffer = null;
} }
m_mode = audio::orchestra::mode_unknow; m_mode = audio::orchestra::mode_unknow;
m_state = audio::orchestra::state::closed; m_state = audio::orchestra::state::closed;
@ -533,8 +525,8 @@ enum audio::orchestra::error audio::orchestra::api::Jack::startStream() {
if ( m_mode == audio::orchestra::mode_output if ( m_mode == audio::orchestra::mode_output
|| m_mode == audio::orchestra::mode_duplex) { || m_mode == audio::orchestra::mode_duplex) {
result = 1; result = 1;
ports = jack_get_ports(m_private->client, m_private->deviceName[0].c_str(), nullptr, JackPortIsInput); ports = jack_get_ports(m_private->client, m_private->deviceName[0].c_str(), null, JackPortIsInput);
if (ports == nullptr) { if (ports == null) {
ATA_ERROR("error determining available JACK input ports!"); ATA_ERROR("error determining available JACK input ports!");
goto unlock; goto unlock;
} }
@ -556,8 +548,8 @@ enum audio::orchestra::error audio::orchestra::api::Jack::startStream() {
if ( m_mode == audio::orchestra::mode_input if ( m_mode == audio::orchestra::mode_input
|| m_mode == audio::orchestra::mode_duplex) { || m_mode == audio::orchestra::mode_duplex) {
result = 1; result = 1;
ports = jack_get_ports(m_private->client, m_private->deviceName[1].c_str(), nullptr, JackPortIsOutput); ports = jack_get_ports(m_private->client, m_private->deviceName[1].c_str(), null, JackPortIsOutput);
if (ports == nullptr) { if (ports == null) {
ATA_ERROR("error determining available JACK output ports!"); ATA_ERROR("error determining available JACK output ports!");
goto unlock; goto unlock;
} }
@ -597,8 +589,7 @@ enum audio::orchestra::error audio::orchestra::api::Jack::stopStream() {
|| m_mode == audio::orchestra::mode_duplex) { || m_mode == audio::orchestra::mode_duplex) {
if (m_private->drainCounter == 0) { if (m_private->drainCounter == 0) {
m_private->drainCounter = 2; m_private->drainCounter = 2;
std::unique_lock<std::mutex> lck(m_mutex); m_private->m_semaphore.wait();
m_private->condition.wait(lck);
} }
} }
jack_deactivate(m_private->client); jack_deactivate(m_private->client);
@ -618,17 +609,6 @@ enum audio::orchestra::error audio::orchestra::api::Jack::abortStream() {
return stopStream(); return stopStream();
} }
// This function will be called by a spawned thread when the user
// callback function signals that the stream should be stopped or
// aborted. It is necessary to handle it this way because the
// callbackEvent() function must return before the jack_deactivate()
// function will return.
static void jackStopStream(void* _userData) {
ethread::setName("Jack_stopStream");
audio::orchestra::api::Jack* myClass = reinterpret_cast<audio::orchestra::api::Jack*>(_userData);
myClass->stopStream();
}
bool audio::orchestra::api::Jack::callbackEvent(uint64_t _nframes) { bool audio::orchestra::api::Jack::callbackEvent(uint64_t _nframes) {
if ( m_state == audio::orchestra::state::stopped if ( m_state == audio::orchestra::state::stopped
|| m_state == audio::orchestra::state::stopping) { || m_state == audio::orchestra::state::stopping) {
@ -646,22 +626,22 @@ bool audio::orchestra::api::Jack::callbackEvent(uint64_t _nframes) {
if (m_private->drainCounter > 3) { if (m_private->drainCounter > 3) {
m_state = audio::orchestra::state::stopping; m_state = audio::orchestra::state::stopping;
if (m_private->internalDrain == true) { if (m_private->internalDrain == true) {
new std::thread(jackStopStream, this); ETK_NEW(ethread::Thread, [&](){stopStream();}, "Jack_stopStream");
} else { } else {
m_private->condition.notify_one(); m_private->m_semaphore.post();
} }
return true; return true;
} }
// Invoke user callback first, to get fresh output data. // Invoke user callback first, to get fresh output data.
if (m_private->drainCounter == 0) { if (m_private->drainCounter == 0) {
audio::Time streamTime = getStreamTime(); audio::Time streamTime = getStreamTime();
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
if (m_mode != audio::orchestra::mode_input && m_private->xrun[0] == true) { if (m_mode != audio::orchestra::mode_input && m_private->xrun[0] == true) {
status.push_back(audio::orchestra::status::underflow); status.pushBack(audio::orchestra::status::underflow);
m_private->xrun[0] = false; m_private->xrun[0] = false;
} }
if (m_mode != audio::orchestra::mode_output && m_private->xrun[1] == true) { if (m_mode != audio::orchestra::mode_output && m_private->xrun[1] == true) {
status.push_back(audio::orchestra::status::overflow); status.pushBack(audio::orchestra::status::overflow);
m_private->xrun[1] = false; m_private->xrun[1] = false;
} }
int32_t cbReturnValue = m_callback(&m_userBuffer[1][0], int32_t cbReturnValue = m_callback(&m_userBuffer[1][0],
@ -673,7 +653,7 @@ bool audio::orchestra::api::Jack::callbackEvent(uint64_t _nframes) {
if (cbReturnValue == 2) { if (cbReturnValue == 2) {
m_state = audio::orchestra::state::stopping; m_state = audio::orchestra::state::stopping;
m_private->drainCounter = 2; m_private->drainCounter = 2;
new std::thread(jackStopStream, this); ETK_NEW(ethread::Thread, [&](){stopStream();}, "Jack_stopStream2");
return true; return true;
} }
else if (cbReturnValue == 1) { else if (cbReturnValue == 1) {

View File

@ -19,7 +19,7 @@ namespace audio {
public: public:
Jack(); Jack();
virtual ~Jack(); virtual ~Jack();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typeJack; return audio::orchestra::typeJack;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();
@ -36,7 +36,6 @@ namespace audio {
bool callbackEvent(uint64_t _nframes); bool callbackEvent(uint64_t _nframes);
private: private:
static int32_t jackXrun(void* _userData); static int32_t jackXrun(void* _userData);
static void jackCloseStream(void* _userData);
static void jackShutdown(void* _userData); static void jackShutdown(void* _userData);
static int32_t jackCallbackHandler(jack_nframes_t _nframes, void* _userData); static int32_t jackCallbackHandler(jack_nframes_t _nframes, void* _userData);
private: private:

View File

@ -8,19 +8,20 @@
#if defined(ORCHESTRA_BUILD_PULSE) #if defined(ORCHESTRA_BUILD_PULSE)
extern "C" {
#include <climits> #include <limits.h>
#include <stdio.h>
}
#include <audio/orchestra/Interface.hpp> #include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <pulse/error.h> #include <pulse/error.h>
#include <pulse/simple.h> #include <pulse/simple.h>
#include <cstdio>
#include <ethread/tools.hpp> #include <ethread/tools.hpp>
#include <audio/orchestra/api/PulseDeviceList.hpp> #include <audio/orchestra/api/PulseDeviceList.hpp>
#include <audio/orchestra/api/Pulse.hpp> #include <audio/orchestra/api/Pulse.hpp>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Pulse::create() { ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Pulse::create() {
return ememory::SharedPtr<audio::orchestra::api::Pulse>(new audio::orchestra::api::Pulse()); return ememory::SharedPtr<audio::orchestra::api::Pulse>(ETK_NEW(audio::orchestra::api::Pulse));
} }
@ -53,9 +54,9 @@ namespace audio {
class PulsePrivate { class PulsePrivate {
public: public:
pa_simple* handle; pa_simple* handle;
ememory::SharedPtr<std::thread> thread; ememory::SharedPtr<ethread::Thread> thread;
bool threadRunning; bool threadRunning;
std::condition_variable runnable_cv; ethread::Semaphore m_semaphore;
bool runnable; bool runnable;
PulsePrivate() : PulsePrivate() :
handle(0), handle(0),
@ -68,7 +69,7 @@ namespace audio {
} }
} }
audio::orchestra::api::Pulse::Pulse() : audio::orchestra::api::Pulse::Pulse() :
m_private(new audio::orchestra::api::PulsePrivate()) { m_private(ETK_NEW(audio::orchestra::api::PulsePrivate)) {
} }
@ -80,7 +81,7 @@ audio::orchestra::api::Pulse::~Pulse() {
uint32_t audio::orchestra::api::Pulse::getDeviceCount() { uint32_t audio::orchestra::api::Pulse::getDeviceCount() {
#if 1 #if 1
std::vector<audio::orchestra::DeviceInfo> list = audio::orchestra::api::pulse::getDeviceList(); etk::Vector<audio::orchestra::DeviceInfo> list = audio::orchestra::api::pulse::getDeviceList();
return list.size(); return list.size();
#else #else
return 1; return 1;
@ -88,7 +89,7 @@ uint32_t audio::orchestra::api::Pulse::getDeviceCount() {
} }
audio::orchestra::DeviceInfo audio::orchestra::api::Pulse::getDeviceInfo(uint32_t _device) { audio::orchestra::DeviceInfo audio::orchestra::api::Pulse::getDeviceInfo(uint32_t _device) {
std::vector<audio::orchestra::DeviceInfo> list = audio::orchestra::api::pulse::getDeviceList(); etk::Vector<audio::orchestra::DeviceInfo> list = audio::orchestra::api::pulse::getDeviceList();
if (_device >= list.size()) { if (_device >= list.size()) {
ATA_ERROR("Request device out of IDs:" << _device << " >= " << list.size()); ATA_ERROR("Request device out of IDs:" << _device << " >= " << list.size());
return audio::orchestra::DeviceInfo(); return audio::orchestra::DeviceInfo();
@ -96,10 +97,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Pulse::getDeviceInfo(uint32_
return list[_device]; return list[_device];
} }
static void pulseaudio_callback(void* _userData) {
audio::orchestra::api::Pulse* myClass = reinterpret_cast<audio::orchestra::api::Pulse*>(_userData);
myClass->callbackEvent();
}
void audio::orchestra::api::Pulse::callbackEvent() { void audio::orchestra::api::Pulse::callbackEvent() {
ethread::setName("Pulse IO-" + m_name); ethread::setName("Pulse IO-" + m_name);
@ -113,15 +111,15 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::closeStream() {
m_mutex.lock(); m_mutex.lock();
if (m_state == audio::orchestra::state::stopped) { if (m_state == audio::orchestra::state::stopped) {
m_private->runnable = true; m_private->runnable = true;
m_private->runnable_cv.notify_one();; m_private->m_semaphore.post();;
} }
m_mutex.unlock(); m_mutex.unLock();
m_private->thread->join(); m_private->thread->join();
if (m_mode == audio::orchestra::mode_output) { if (m_mode == audio::orchestra::mode_output) {
pa_simple_flush(m_private->handle, nullptr); pa_simple_flush(m_private->handle, null);
} }
pa_simple_free(m_private->handle); pa_simple_free(m_private->handle);
m_private->handle = nullptr; m_private->handle = null;
m_userBuffer[0].clear(); m_userBuffer[0].clear();
m_userBuffer[1].clear(); m_userBuffer[1].clear();
m_state = audio::orchestra::state::closed; m_state = audio::orchestra::state::closed;
@ -131,12 +129,11 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::closeStream() {
void audio::orchestra::api::Pulse::callbackEventOneCycle() { void audio::orchestra::api::Pulse::callbackEventOneCycle() {
if (m_state == audio::orchestra::state::stopped) { if (m_state == audio::orchestra::state::stopped) {
std::unique_lock<std::mutex> lck(m_mutex);
while (!m_private->runnable) { while (!m_private->runnable) {
m_private->runnable_cv.wait(lck); m_private->m_semaphore.wait();
} }
if (m_state != audio::orchestra::state::running) { if (m_state != audio::orchestra::state::running) {
m_mutex.unlock(); m_mutex.unLock();
return; return;
} }
} }
@ -145,7 +142,7 @@ void audio::orchestra::api::Pulse::callbackEventOneCycle() {
return; return;
} }
audio::Time streamTime = getStreamTime(); audio::Time streamTime = getStreamTime();
std::vector<enum audio::orchestra::status> status; etk::Vector<enum audio::orchestra::status> status;
int32_t doStopStream = m_callback(&m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)][0], int32_t doStopStream = m_callback(&m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)][0],
streamTime, streamTime,
&m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)][0], &m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)][0],
@ -160,7 +157,7 @@ void audio::orchestra::api::Pulse::callbackEventOneCycle() {
void *pulse_in = m_doConvertBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)] ? m_deviceBuffer : &m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)][0]; void *pulse_in = m_doConvertBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)] ? m_deviceBuffer : &m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)][0];
void *pulse_out = m_doConvertBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)] ? m_deviceBuffer : &m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)][0]; void *pulse_out = m_doConvertBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)] ? m_deviceBuffer : &m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)][0];
if (m_state != audio::orchestra::state::running) { if (m_state != audio::orchestra::state::running) {
goto unlock; goto unLock;
} }
int32_t pa_error; int32_t pa_error;
size_t bytes; size_t bytes;
@ -194,8 +191,8 @@ void audio::orchestra::api::Pulse::callbackEventOneCycle() {
m_convertInfo[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)]); m_convertInfo[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)]);
} }
} }
unlock: unLock:
m_mutex.unlock(); m_mutex.unLock();
audio::orchestra::Api::tickStreamTime(); audio::orchestra::Api::tickStreamTime();
if (doStopStream == 1) { if (doStopStream == 1) {
stopStream(); stopStream();
@ -218,8 +215,8 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::startStream() {
m_mutex.lock(); m_mutex.lock();
m_state = audio::orchestra::state::running; m_state = audio::orchestra::state::running;
m_private->runnable = true; m_private->runnable = true;
m_private->runnable_cv.notify_one(); m_private->m_semaphore.post();
m_mutex.unlock(); m_mutex.unLock();
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
@ -234,18 +231,18 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::stopStream() {
} }
m_state = audio::orchestra::state::stopped; m_state = audio::orchestra::state::stopped;
m_mutex.lock(); m_mutex.lock();
if ( m_private != nullptr if ( m_private != null
&& m_private->handle != nullptr && m_private->handle != null
&& m_mode == audio::orchestra::mode_output) { && m_mode == audio::orchestra::mode_output) {
int32_t pa_error; int32_t pa_error;
if (pa_simple_drain(m_private->handle, &pa_error) < 0) { if (pa_simple_drain(m_private->handle, &pa_error) < 0) {
ATA_ERROR("error draining output device, " << pa_strerror(pa_error) << "."); ATA_ERROR("error draining output device, " << pa_strerror(pa_error) << ".");
m_mutex.unlock(); m_mutex.unLock();
return audio::orchestra::error_systemError; return audio::orchestra::error_systemError;
} }
} }
m_state = audio::orchestra::state::stopped; m_state = audio::orchestra::state::stopped;
m_mutex.unlock(); m_mutex.unLock();
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
@ -260,18 +257,18 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::abortStream() {
} }
m_state = audio::orchestra::state::stopped; m_state = audio::orchestra::state::stopped;
m_mutex.lock(); m_mutex.lock();
if ( m_private != nullptr if ( m_private != null
&& m_private->handle != nullptr && m_private->handle != null
&& m_mode == audio::orchestra::mode_output) { && m_mode == audio::orchestra::mode_output) {
int32_t pa_error; int32_t pa_error;
if (pa_simple_flush(m_private->handle, &pa_error) < 0) { if (pa_simple_flush(m_private->handle, &pa_error) < 0) {
ATA_ERROR("error flushing output device, " << pa_strerror(pa_error) << "."); ATA_ERROR("error flushing output device, " << pa_strerror(pa_error) << ".");
m_mutex.unlock(); m_mutex.unLock();
return audio::orchestra::error_systemError; return audio::orchestra::error_systemError;
} }
} }
m_state = audio::orchestra::state::stopped; m_state = audio::orchestra::state::stopped;
m_mutex.unlock(); m_mutex.unLock();
return audio::orchestra::error_none; return audio::orchestra::error_none;
} }
@ -356,7 +353,7 @@ bool audio::orchestra::api::Pulse::open(uint32_t _device,
bufferBytes *= *_bufferSize; bufferBytes *= *_bufferSize;
if (m_deviceBuffer) free(m_deviceBuffer); if (m_deviceBuffer) free(m_deviceBuffer);
m_deviceBuffer = (char *) calloc(bufferBytes, 1); m_deviceBuffer = (char *) calloc(bufferBytes, 1);
if (m_deviceBuffer == nullptr) { if (m_deviceBuffer == null) {
ATA_ERROR("error allocating device buffer memory."); ATA_ERROR("error allocating device buffer memory.");
goto error; goto error;
} }
@ -370,15 +367,15 @@ bool audio::orchestra::api::Pulse::open(uint32_t _device,
int32_t error; int32_t error;
switch (_mode) { switch (_mode) {
case audio::orchestra::mode_input: case audio::orchestra::mode_input:
m_private->handle = pa_simple_new(nullptr, "orchestra", PA_STREAM_RECORD, nullptr, "Record", &ss, nullptr, nullptr, &error); m_private->handle = pa_simple_new(null, "orchestra", PA_STREAM_RECORD, null, "Record", &ss, null, null, &error);
if (m_private->handle == nullptr) { if (m_private->handle == null) {
ATA_ERROR("error connecting input to PulseAudio server."); ATA_ERROR("error connecting input to PulseAudio server.");
goto error; goto error;
} }
break; break;
case audio::orchestra::mode_output: case audio::orchestra::mode_output:
m_private->handle = pa_simple_new(nullptr, "orchestra", PA_STREAM_PLAYBACK, nullptr, "Playback", &ss, nullptr, nullptr, &error); m_private->handle = pa_simple_new(null, "orchestra", PA_STREAM_PLAYBACK, null, "Playback", &ss, null, null, &error);
if (m_private->handle == nullptr) { if (m_private->handle == null) {
ATA_ERROR("error connecting output to PulseAudio server."); ATA_ERROR("error connecting output to PulseAudio server.");
goto error; goto error;
} }
@ -393,8 +390,8 @@ bool audio::orchestra::api::Pulse::open(uint32_t _device,
} }
if (m_private->threadRunning == false) { if (m_private->threadRunning == false) {
m_private->threadRunning = true; m_private->threadRunning = true;
m_private->thread = ememory::makeShared<std::thread>(&pulseaudio_callback, this); m_private->thread = ememory::makeShared<ethread::Thread>([&](){callbackEvent();}, "pulseCallback");
if (m_private->thread == nullptr) { if (m_private->thread == null) {
ATA_ERROR("error creating thread."); ATA_ERROR("error creating thread.");
goto error; goto error;
} }

View File

@ -17,7 +17,7 @@ namespace audio {
public: public:
Pulse(); Pulse();
virtual ~Pulse(); virtual ~Pulse();
const std::string& getCurrentApi() { const etk::String& getCurrentApi() {
return audio::orchestra::typePulse; return audio::orchestra::typePulse;
} }
uint32_t getDeviceCount(); uint32_t getDeviceCount();
@ -34,7 +34,7 @@ namespace audio {
void callbackEvent(); void callbackEvent();
private: private:
ememory::SharedPtr<PulsePrivate> m_private; ememory::SharedPtr<PulsePrivate> m_private;
std::vector<audio::orchestra::DeviceInfo> m_devices; etk::Vector<audio::orchestra::DeviceInfo> m_devices;
void saveDeviceInfo(); void saveDeviceInfo();
bool open(uint32_t _device, bool open(uint32_t _device,
audio::orchestra::mode _mode, audio::orchestra::mode _mode,

View File

@ -6,10 +6,11 @@
*/ */
#if defined(ORCHESTRA_BUILD_PULSE) #if defined(ORCHESTRA_BUILD_PULSE)
extern "C" {
#include <cstdio> #include <stdio.h>
#include <cstring> #include <string.h>
#include <pulse/pulseaudio.hpp> }
#include <pulse/pulseaudio.h>
#include <audio/orchestra/api/PulseDeviceList.hpp> #include <audio/orchestra/api/PulseDeviceList.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <audio/Time.hpp> #include <audio/Time.hpp>
@ -105,101 +106,101 @@ static audio::format getFormatFromPulseFormat(enum pa_sample_format _format) {
return audio::format_unknow; return audio::format_unknow;
} }
static std::vector<audio::channel> getChannelOrderFromPulseChannel(const struct pa_channel_map& _map) { static etk::Vector<audio::channel> getChannelOrderFromPulseChannel(const struct pa_channel_map& _map) {
std::vector<audio::channel> out; etk::Vector<audio::channel> out;
for (int32_t iii=0; iii<_map.channels; ++iii) { for (int32_t iii=0; iii<_map.channels; ++iii) {
switch(_map.map[iii]) { switch(_map.map[iii]) {
default: default:
case PA_CHANNEL_POSITION_MAX: case PA_CHANNEL_POSITION_MAX:
case PA_CHANNEL_POSITION_INVALID: case PA_CHANNEL_POSITION_INVALID:
out.push_back(audio::channel_unknow); out.pushBack(audio::channel_unknow);
break; break;
case PA_CHANNEL_POSITION_MONO: case PA_CHANNEL_POSITION_MONO:
case PA_CHANNEL_POSITION_FRONT_CENTER: case PA_CHANNEL_POSITION_FRONT_CENTER:
out.push_back(audio::channel_frontCenter); out.pushBack(audio::channel_frontCenter);
break; break;
case PA_CHANNEL_POSITION_FRONT_LEFT: case PA_CHANNEL_POSITION_FRONT_LEFT:
out.push_back(audio::channel_frontLeft); out.pushBack(audio::channel_frontLeft);
break; break;
case PA_CHANNEL_POSITION_FRONT_RIGHT: case PA_CHANNEL_POSITION_FRONT_RIGHT:
out.push_back(audio::channel_frontRight); out.pushBack(audio::channel_frontRight);
break; break;
case PA_CHANNEL_POSITION_REAR_CENTER: case PA_CHANNEL_POSITION_REAR_CENTER:
out.push_back(audio::channel_rearCenter); out.pushBack(audio::channel_rearCenter);
break; break;
case PA_CHANNEL_POSITION_REAR_LEFT: case PA_CHANNEL_POSITION_REAR_LEFT:
out.push_back(audio::channel_rearLeft); out.pushBack(audio::channel_rearLeft);
break; break;
case PA_CHANNEL_POSITION_REAR_RIGHT: case PA_CHANNEL_POSITION_REAR_RIGHT:
out.push_back(audio::channel_rearRight); out.pushBack(audio::channel_rearRight);
break; break;
case PA_CHANNEL_POSITION_LFE: case PA_CHANNEL_POSITION_LFE:
out.push_back(audio::channel_lfe); out.pushBack(audio::channel_lfe);
break; break;
case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:
out.push_back(audio::channel_centerLeft); out.pushBack(audio::channel_centerLeft);
break; break;
case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER:
out.push_back(audio::channel_centerRight); out.pushBack(audio::channel_centerRight);
break; break;
case PA_CHANNEL_POSITION_SIDE_LEFT: case PA_CHANNEL_POSITION_SIDE_LEFT:
out.push_back(audio::channel_topCenterLeft); out.pushBack(audio::channel_topCenterLeft);
break; break;
case PA_CHANNEL_POSITION_SIDE_RIGHT: case PA_CHANNEL_POSITION_SIDE_RIGHT:
out.push_back(audio::channel_topCenterRight); out.pushBack(audio::channel_topCenterRight);
break; break;
case PA_CHANNEL_POSITION_TOP_CENTER: case PA_CHANNEL_POSITION_TOP_CENTER:
case PA_CHANNEL_POSITION_TOP_FRONT_CENTER: case PA_CHANNEL_POSITION_TOP_FRONT_CENTER:
out.push_back(audio::channel_topFrontCenter); out.pushBack(audio::channel_topFrontCenter);
break; break;
case PA_CHANNEL_POSITION_TOP_FRONT_LEFT: case PA_CHANNEL_POSITION_TOP_FRONT_LEFT:
out.push_back(audio::channel_topFrontLeft); out.pushBack(audio::channel_topFrontLeft);
break; break;
case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT: case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:
out.push_back(audio::channel_topFrontRight); out.pushBack(audio::channel_topFrontRight);
break; break;
case PA_CHANNEL_POSITION_TOP_REAR_LEFT: case PA_CHANNEL_POSITION_TOP_REAR_LEFT:
out.push_back(audio::channel_topRearLeft); out.pushBack(audio::channel_topRearLeft);
break; break;
case PA_CHANNEL_POSITION_TOP_REAR_RIGHT: case PA_CHANNEL_POSITION_TOP_REAR_RIGHT:
out.push_back(audio::channel_topRearRight); out.pushBack(audio::channel_topRearRight);
break; break;
case PA_CHANNEL_POSITION_TOP_REAR_CENTER: case PA_CHANNEL_POSITION_TOP_REAR_CENTER:
out.push_back(audio::channel_topRearCenter); out.pushBack(audio::channel_topRearCenter);
break; break;
case PA_CHANNEL_POSITION_AUX0: out.push_back(audio::channel_aux0); break; case PA_CHANNEL_POSITION_AUX0: out.pushBack(audio::channel_aux0); break;
case PA_CHANNEL_POSITION_AUX1: out.push_back(audio::channel_aux1); break; case PA_CHANNEL_POSITION_AUX1: out.pushBack(audio::channel_aux1); break;
case PA_CHANNEL_POSITION_AUX2: out.push_back(audio::channel_aux2); break; case PA_CHANNEL_POSITION_AUX2: out.pushBack(audio::channel_aux2); break;
case PA_CHANNEL_POSITION_AUX3: out.push_back(audio::channel_aux3); break; case PA_CHANNEL_POSITION_AUX3: out.pushBack(audio::channel_aux3); break;
case PA_CHANNEL_POSITION_AUX4: out.push_back(audio::channel_aux4); break; case PA_CHANNEL_POSITION_AUX4: out.pushBack(audio::channel_aux4); break;
case PA_CHANNEL_POSITION_AUX5: out.push_back(audio::channel_aux5); break; case PA_CHANNEL_POSITION_AUX5: out.pushBack(audio::channel_aux5); break;
case PA_CHANNEL_POSITION_AUX6: out.push_back(audio::channel_aux6); break; case PA_CHANNEL_POSITION_AUX6: out.pushBack(audio::channel_aux6); break;
case PA_CHANNEL_POSITION_AUX7: out.push_back(audio::channel_aux7); break; case PA_CHANNEL_POSITION_AUX7: out.pushBack(audio::channel_aux7); break;
case PA_CHANNEL_POSITION_AUX8: out.push_back(audio::channel_aux8); break; case PA_CHANNEL_POSITION_AUX8: out.pushBack(audio::channel_aux8); break;
case PA_CHANNEL_POSITION_AUX9: out.push_back(audio::channel_aux9); break; case PA_CHANNEL_POSITION_AUX9: out.pushBack(audio::channel_aux9); break;
case PA_CHANNEL_POSITION_AUX10: out.push_back(audio::channel_aux10); break; case PA_CHANNEL_POSITION_AUX10: out.pushBack(audio::channel_aux10); break;
case PA_CHANNEL_POSITION_AUX11: out.push_back(audio::channel_aux11); break; case PA_CHANNEL_POSITION_AUX11: out.pushBack(audio::channel_aux11); break;
case PA_CHANNEL_POSITION_AUX12: out.push_back(audio::channel_aux12); break; case PA_CHANNEL_POSITION_AUX12: out.pushBack(audio::channel_aux12); break;
case PA_CHANNEL_POSITION_AUX13: out.push_back(audio::channel_aux13); break; case PA_CHANNEL_POSITION_AUX13: out.pushBack(audio::channel_aux13); break;
case PA_CHANNEL_POSITION_AUX14: out.push_back(audio::channel_aux14); break; case PA_CHANNEL_POSITION_AUX14: out.pushBack(audio::channel_aux14); break;
case PA_CHANNEL_POSITION_AUX15: out.push_back(audio::channel_aux15); break; case PA_CHANNEL_POSITION_AUX15: out.pushBack(audio::channel_aux15); break;
case PA_CHANNEL_POSITION_AUX16: out.push_back(audio::channel_aux16); break; case PA_CHANNEL_POSITION_AUX16: out.pushBack(audio::channel_aux16); break;
case PA_CHANNEL_POSITION_AUX17: out.push_back(audio::channel_aux17); break; case PA_CHANNEL_POSITION_AUX17: out.pushBack(audio::channel_aux17); break;
case PA_CHANNEL_POSITION_AUX18: out.push_back(audio::channel_aux18); break; case PA_CHANNEL_POSITION_AUX18: out.pushBack(audio::channel_aux18); break;
case PA_CHANNEL_POSITION_AUX19: out.push_back(audio::channel_aux19); break; case PA_CHANNEL_POSITION_AUX19: out.pushBack(audio::channel_aux19); break;
case PA_CHANNEL_POSITION_AUX20: out.push_back(audio::channel_aux20); break; case PA_CHANNEL_POSITION_AUX20: out.pushBack(audio::channel_aux20); break;
case PA_CHANNEL_POSITION_AUX21: out.push_back(audio::channel_aux21); break; case PA_CHANNEL_POSITION_AUX21: out.pushBack(audio::channel_aux21); break;
case PA_CHANNEL_POSITION_AUX22: out.push_back(audio::channel_aux22); break; case PA_CHANNEL_POSITION_AUX22: out.pushBack(audio::channel_aux22); break;
case PA_CHANNEL_POSITION_AUX23: out.push_back(audio::channel_aux23); break; case PA_CHANNEL_POSITION_AUX23: out.pushBack(audio::channel_aux23); break;
case PA_CHANNEL_POSITION_AUX24: out.push_back(audio::channel_aux24); break; case PA_CHANNEL_POSITION_AUX24: out.pushBack(audio::channel_aux24); break;
case PA_CHANNEL_POSITION_AUX25: out.push_back(audio::channel_aux25); break; case PA_CHANNEL_POSITION_AUX25: out.pushBack(audio::channel_aux25); break;
case PA_CHANNEL_POSITION_AUX26: out.push_back(audio::channel_aux26); break; case PA_CHANNEL_POSITION_AUX26: out.pushBack(audio::channel_aux26); break;
case PA_CHANNEL_POSITION_AUX27: out.push_back(audio::channel_aux27); break; case PA_CHANNEL_POSITION_AUX27: out.pushBack(audio::channel_aux27); break;
case PA_CHANNEL_POSITION_AUX28: out.push_back(audio::channel_aux28); break; case PA_CHANNEL_POSITION_AUX28: out.pushBack(audio::channel_aux28); break;
case PA_CHANNEL_POSITION_AUX29: out.push_back(audio::channel_aux29); break; case PA_CHANNEL_POSITION_AUX29: out.pushBack(audio::channel_aux29); break;
case PA_CHANNEL_POSITION_AUX30: out.push_back(audio::channel_aux30); break; case PA_CHANNEL_POSITION_AUX30: out.pushBack(audio::channel_aux30); break;
case PA_CHANNEL_POSITION_AUX31: out.push_back(audio::channel_aux31); break; case PA_CHANNEL_POSITION_AUX31: out.pushBack(audio::channel_aux31); break;
} }
} }
@ -207,7 +208,7 @@ static std::vector<audio::channel> getChannelOrderFromPulseChannel(const struct
} }
// Callback on getting data from pulseaudio: // Callback on getting data from pulseaudio:
static void callbackGetSinkList(pa_context* _contex, const pa_sink_info* _info, int _eol, void* _userdata) { static void callbackGetSinkList(pa_context* _contex, const pa_sink_info* _info, int _eol, void* _userdata) {
std::vector<audio::orchestra::DeviceInfo>* list = static_cast<std::vector<audio::orchestra::DeviceInfo>*>(_userdata); etk::Vector<audio::orchestra::DeviceInfo>* list = static_cast<etk::Vector<audio::orchestra::DeviceInfo>*>(_userdata);
// If eol is set to a positive number, you're at the end of the list // If eol is set to a positive number, you're at the end of the list
if (_eol > 0) { if (_eol > 0) {
return; return;
@ -217,17 +218,17 @@ static void callbackGetSinkList(pa_context* _contex, const pa_sink_info* _info,
info.input = false; info.input = false;
info.name = _info->name; info.name = _info->name;
info.desc = _info->description; info.desc = _info->description;
info.sampleRates.push_back(_info->sample_spec.rate); info.sampleRates.pushBack(_info->sample_spec.rate);
info.nativeFormats.push_back(getFormatFromPulseFormat(_info->sample_spec.format)); info.nativeFormats.pushBack(getFormatFromPulseFormat(_info->sample_spec.format));
info.channels = getChannelOrderFromPulseChannel(_info->channel_map); info.channels = getChannelOrderFromPulseChannel(_info->channel_map);
ATA_VERBOSE("plop=" << _info->index << " " << _info->name); ATA_VERBOSE("plop=" << _info->index << " " << _info->name);
//ATA_DEBUG(" ports=" << _info->n_ports); //ATA_DEBUG(" ports=" << _info->n_ports);
list->push_back(info); list->pushBack(info);
} }
// allback to get data from pulseaudio: // allback to get data from pulseaudio:
static void callbackGetSourceList(pa_context* _contex, const pa_source_info* _info, int _eol, void* _userdata) { static void callbackGetSourceList(pa_context* _contex, const pa_source_info* _info, int _eol, void* _userdata) {
std::vector<audio::orchestra::DeviceInfo>* list = static_cast<std::vector<audio::orchestra::DeviceInfo>*>(_userdata); etk::Vector<audio::orchestra::DeviceInfo>* list = static_cast<etk::Vector<audio::orchestra::DeviceInfo>*>(_userdata);
if (_eol > 0) { if (_eol > 0) {
return; return;
} }
@ -236,18 +237,18 @@ static void callbackGetSourceList(pa_context* _contex, const pa_source_info* _in
info.input = true; info.input = true;
info.name = _info->name; info.name = _info->name;
info.desc = _info->description; info.desc = _info->description;
info.sampleRates.push_back(_info->sample_spec.rate); info.sampleRates.pushBack(_info->sample_spec.rate);
info.nativeFormats.push_back(getFormatFromPulseFormat(_info->sample_spec.format)); info.nativeFormats.pushBack(getFormatFromPulseFormat(_info->sample_spec.format));
info.channels = getChannelOrderFromPulseChannel(_info->channel_map); info.channels = getChannelOrderFromPulseChannel(_info->channel_map);
ATA_VERBOSE("plop=" << _info->index << " " << _info->name); ATA_VERBOSE("plop=" << _info->index << " " << _info->name);
list->push_back(info); list->pushBack(info);
} }
// to not update all the time ... // to not update all the time ...
static std::vector<audio::orchestra::DeviceInfo> pulseAudioListOfDevice; static etk::Vector<audio::orchestra::DeviceInfo> pulseAudioListOfDevice;
static audio::Time pulseAudioListOfDeviceTime; static audio::Time pulseAudioListOfDeviceTime;
std::vector<audio::orchestra::DeviceInfo> audio::orchestra::api::pulse::getDeviceList() { etk::Vector<audio::orchestra::DeviceInfo> audio::orchestra::api::pulse::getDeviceList() {
audio::Duration delta = audio::Time::now() - pulseAudioListOfDeviceTime; audio::Duration delta = audio::Time::now() - pulseAudioListOfDeviceTime;
if (delta < audio::Duration(30,0)) { if (delta < audio::Duration(30,0)) {
return pulseAudioListOfDevice; return pulseAudioListOfDevice;
@ -258,7 +259,7 @@ std::vector<audio::orchestra::DeviceInfo> audio::orchestra::api::pulse::getDevic
pa_operation* pulseAudioOperation; pa_operation* pulseAudioOperation;
pa_context* pulseAudioContex; pa_context* pulseAudioContex;
pa_context_flags_t pulseAudioFlags = PA_CONTEXT_NOAUTOSPAWN; pa_context_flags_t pulseAudioFlags = PA_CONTEXT_NOAUTOSPAWN;
std::vector<audio::orchestra::DeviceInfo>& out = pulseAudioListOfDevice; etk::Vector<audio::orchestra::DeviceInfo>& out = pulseAudioListOfDevice;
out.clear(); out.clear();
// We'll need these state variables to keep track of our requests // We'll need these state variables to keep track of our requests
int state = 0; int state = 0;
@ -276,7 +277,7 @@ std::vector<audio::orchestra::DeviceInfo> audio::orchestra::api::pulse::getDevic
// We can't do anything until PA is ready, so just iterate the mainloop // We can't do anything until PA is ready, so just iterate the mainloop
// and continue // and continue
if (pulseAudioReady == 0) { if (pulseAudioReady == 0) {
pa_mainloop_iterate(pulseAudioMainLoop, 1, nullptr); pa_mainloop_iterate(pulseAudioMainLoop, 1, null);
continue; continue;
} }
// We couldn't get a connection to the server, so exit out // We couldn't get a connection to the server, so exit out
@ -330,7 +331,7 @@ std::vector<audio::orchestra::DeviceInfo> audio::orchestra::api::pulse::getDevic
} }
// Iterate the main loop .. // Iterate the main loop ..
if (playLoop == true) { if (playLoop == true) {
pa_mainloop_iterate(pulseAudioMainLoop, 1, nullptr); pa_mainloop_iterate(pulseAudioMainLoop, 1, null);
} }
} }
// TODO: need to do it better ... // TODO: need to do it better ...

View File

@ -14,7 +14,7 @@ namespace audio {
namespace orchestra { namespace orchestra {
namespace api { namespace api {
namespace pulse { namespace pulse {
std::vector<audio::orchestra::DeviceInfo> getDeviceList(); etk::Vector<audio::orchestra::DeviceInfo> getDeviceList();
} }
} }
} }

View File

@ -6,11 +6,11 @@
*/ */
#pragma once #pragma once
#include <thread> #include <ethread/Thread.hpp>
#include <condition_variable> #include <ethread/Semaphore.hpp>
#include <mutex> #include <ethread/Mutex.hpp>
#include <chrono> #include <echrono/Steady.hpp>
#include <functional> #include <etk/Function.hpp>
#include <ememory/memory.hpp> #include <ememory/memory.hpp>
#include <audio/channel.hpp> #include <audio/channel.hpp>
#include <audio/format.hpp> #include <audio/format.hpp>

View File

@ -20,7 +20,7 @@ int32_t audio::orchestra::modeToIdTable(enum mode _mode) {
return 0; return 0;
} }
std::ostream& audio::operator <<(std::ostream& _os, enum audio::orchestra::mode _obj) { etk::Stream& audio::operator <<(etk::Stream& _os, enum audio::orchestra::mode _obj) {
switch (_obj) { switch (_obj) {
case audio::orchestra::mode_unknow: case audio::orchestra::mode_unknow:
_os << "unknow"; _os << "unknow";
@ -36,4 +36,4 @@ std::ostream& audio::operator <<(std::ostream& _os, enum audio::orchestra::mode
break; break;
} }
return _os; return _os;
} }

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/Stream.hpp>
namespace audio { namespace audio {
namespace orchestra { namespace orchestra {
@ -18,6 +19,6 @@ namespace audio {
}; };
int32_t modeToIdTable(enum mode _mode); int32_t modeToIdTable(enum mode _mode);
} }
std::ostream& operator <<(std::ostream& _os, enum audio::orchestra::mode _obj); etk::Stream& operator <<(etk::Stream& _os, enum audio::orchestra::mode _obj);
} }

View File

@ -13,20 +13,20 @@ static const char* listValue[] = {
"underflow" "underflow"
}; };
std::ostream& audio::orchestra::operator <<(std::ostream& _os, enum audio::orchestra::status _obj) { etk::Stream& audio::orchestra::operator <<(etk::Stream& _os, enum audio::orchestra::status _obj) {
_os << listValue[int32_t(_obj)]; _os << listValue[int32_t(_obj)];
return _os; return _os;
} }
std::ostream& audio::orchestra::operator <<(std::ostream& _os, const std::vector<enum audio::orchestra::status>& _obj) { etk::Stream& audio::orchestra::operator <<(etk::Stream& _os, const etk::Vector<enum audio::orchestra::status>& _obj) {
_os << std::string("{"); _os << etk::String("{");
for (size_t iii=0; iii<_obj.size(); ++iii) { for (size_t iii=0; iii<_obj.size(); ++iii) {
if (iii!=0) { if (iii!=0) {
_os << std::string(";"); _os << etk::String(";");
} }
_os << _obj[iii]; _os << _obj[iii];
} }
_os << std::string("}"); _os << etk::String("}");
return _os; return _os;
} }

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/Vector.hpp>
namespace audio { namespace audio {
namespace orchestra { namespace orchestra {
@ -15,8 +16,8 @@ namespace audio {
overflow, //!< Internal buffer has more data than they can accept overflow, //!< Internal buffer has more data than they can accept
underflow //!< The internal buffer is empty underflow //!< The internal buffer is empty
}; };
std::ostream& operator <<(std::ostream& _os, enum audio::orchestra::status _obj); etk::Stream& operator <<(etk::Stream& _os, enum audio::orchestra::status _obj);
std::ostream& operator <<(std::ostream& _os, const std::vector<enum audio::orchestra::status>& _obj); etk::Stream& operator <<(etk::Stream& _os, const etk::Vector<enum audio::orchestra::status>& _obj);
} }
} }

View File

@ -7,19 +7,15 @@
#include <audio/orchestra/type.hpp> #include <audio/orchestra/type.hpp>
#include <audio/orchestra/debug.hpp> #include <audio/orchestra/debug.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <climits>
const std::string audio::orchestra::typeUndefined = "undefined"; const etk::String audio::orchestra::typeUndefined = "undefined";
const std::string audio::orchestra::typeAlsa = "alsa"; const etk::String audio::orchestra::typeAlsa = "alsa";
const std::string audio::orchestra::typePulse = "pulse"; const etk::String audio::orchestra::typePulse = "pulse";
const std::string audio::orchestra::typeOss = "oss"; const etk::String audio::orchestra::typeOss = "oss";
const std::string audio::orchestra::typeJack = "jack"; const etk::String audio::orchestra::typeJack = "jack";
const std::string audio::orchestra::typeCoreOSX = "coreOSX"; const etk::String audio::orchestra::typeCoreOSX = "coreOSX";
const std::string audio::orchestra::typeCoreIOS = "coreIOS"; const etk::String audio::orchestra::typeCoreIOS = "coreIOS";
const std::string audio::orchestra::typeAsio = "asio"; const etk::String audio::orchestra::typeAsio = "asio";
const std::string audio::orchestra::typeDs = "ds"; const etk::String audio::orchestra::typeDs = "ds";
const std::string audio::orchestra::typeJava = "java"; const etk::String audio::orchestra::typeJava = "java";
const std::string audio::orchestra::typeDummy = "dummy"; const etk::String audio::orchestra::typeDummy = "dummy";

View File

@ -14,17 +14,17 @@ namespace audio {
/** /**
* @brief Audio API specifier arguments. * @brief Audio API specifier arguments.
*/ */
extern const std::string typeUndefined; //!< Error API. extern const etk::String typeUndefined; //!< Error API.
extern const std::string typeAlsa; //!< LINUX The Advanced Linux Sound Architecture. extern const etk::String typeAlsa; //!< LINUX The Advanced Linux Sound Architecture.
extern const std::string typePulse; //!< LINUX The Linux PulseAudio. extern const etk::String typePulse; //!< LINUX The Linux PulseAudio.
extern const std::string typeOss; //!< LINUX The Linux Open Sound System. extern const etk::String typeOss; //!< LINUX The Linux Open Sound System.
extern const std::string typeJack; //!< UNIX The Jack Low-Latency Audio Server. extern const etk::String typeJack; //!< UNIX The Jack Low-Latency Audio Server.
extern const std::string typeCoreOSX; //!< Macintosh OSX Core Audio. extern const etk::String typeCoreOSX; //!< Macintosh OSX Core Audio.
extern const std::string typeCoreIOS; //!< Macintosh iOS Core Audio. extern const etk::String typeCoreIOS; //!< Macintosh iOS Core Audio.
extern const std::string typeAsio; //!< WINDOWS The Steinberg Audio Stream I/O. extern const etk::String typeAsio; //!< WINDOWS The Steinberg Audio Stream I/O.
extern const std::string typeDs; //!< WINDOWS The Microsoft Direct Sound. extern const etk::String typeDs; //!< WINDOWS The Microsoft Direct Sound.
extern const std::string typeJava; //!< ANDROID Interface. extern const etk::String typeJava; //!< ANDROID Interface.
extern const std::string typeDummy; //!< Empty wrapper (non-functional). extern const etk::String typeDummy; //!< Empty wrapper (non-functional).
} }
} }

View File

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.tools as tools import lutin.tools as tools
import lutin.debug as debug import realog.debug as debug
def get_type(): def get_type():

View File

@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.debug as debug import realog.debug as debug
import lutin.tools as tools import lutin.tools as tools

View File

@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.debug as debug import realog.debug as debug
import lutin.tools as tools import lutin.tools as tools

View File

@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.debug as debug import realog.debug as debug
import lutin.tools as tools import lutin.tools as tools

View File

@ -13,11 +13,11 @@ int main(int _argc, const char **_argv) {
// the only one init for etk: // the only one init for etk:
etk::init(_argc, _argv); etk::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; etk::String data = _argv[iii];
if ( data == "-h" if ( data == "-h"
|| data == "--help") { || data == "--help") {
std::cout << "Help : " << std::endl; TEST_PRINT("Help : ");
std::cout << " ./xxx ---" << std::endl; TEST_PRINT(" ./xxx ---");
exit(0); exit(0);
} }
} }

View File

@ -13,16 +13,16 @@ int main(int _argc, const char **_argv) {
// the only one init for etk: // the only one init for etk:
etk::init(_argc, _argv); etk::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; etk::String data = _argv[iii];
if ( data == "-h" if ( data == "-h"
|| data == "--help") { || data == "--help") {
std::cout << "Help : " << std::endl; TEST_PRINT("Help : ");
std::cout << " ./xxx ---" << std::endl; TEST_PRINT(" ./xxx ---");
exit(0); exit(0);
} }
} }
audio::orchestra::Interface interface; audio::orchestra::Interface interface;
std::vector<std::string> apis = interface.getListApi(); etk::Vector<etk::String> apis = interface.getListApi();
TEST_PRINT("Find : " << apis.size() << " apis."); TEST_PRINT("Find : " << apis.size() << " apis.");
for (auto &it : apis) { for (auto &it : apis) {
interface.instanciate(it); interface.instanciate(it);

View File

@ -13,11 +13,11 @@ int main(int _argc, const char **_argv) {
// the only one init for etk: // the only one init for etk:
etk::init(_argc, _argv); etk::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; etk::String data = _argv[iii];
if ( data == "-h" if ( data == "-h"
|| data == "--help") { || data == "--help") {
std::cout << "Help : " << std::endl; TEST_PRINT("Help : ");
std::cout << " ./xxx ---" << std::endl; TEST_PRINT(" ./xxx ---");
exit(0); exit(0);
} }
} }

View File

@ -1 +1 @@
0.4.0 1.0.0