[DEV] update new ETK

This commit is contained in:
Edouard DUPIN 2017-09-26 15:57:44 +02:00
parent 4bc3ff2f1a
commit 309b63254f
26 changed files with 139 additions and 164 deletions

View File

@ -8,10 +8,7 @@
//#include <etk/types.hpp>
#include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <etk/types.hpp>
// Static variable definitions.
const etk::Vector<uint32_t>& audio::orchestra::genericSampleRate() {
@ -55,7 +52,7 @@ audio::orchestra::Api::~Api() {
enum audio::orchestra::error audio::orchestra::Api::startStream() {
ATA_VERBOSE("Start Stream");
m_startTime = audio::Time::now();
m_duration = std::chrono::microseconds(0);
m_duration = echrono::microseconds(0);
return audio::orchestra::error_none;
}

View File

@ -6,7 +6,7 @@
*/
#pragma once
#include <sstream>
#include <etk/Stream.hpp>
#include <audio/orchestra/debug.hpp>
#include <audio/orchestra/type.hpp>
#include <audio/orchestra/state.hpp>
@ -33,11 +33,11 @@ namespace audio {
* @param _status List of error that occured in the laps of time.
*/
typedef etk::Function<int32_t (const void* _inputBuffer,
const audio::Time& _timeInput,
void* _outputBuffer,
const audio::Time& _timeOutput,
uint32_t _nbChunk,
const etk::Vector<audio::orchestra::status>& _status)> AirTAudioCallback;
const audio::Time& _timeInput,
void* _outputBuffer,
const audio::Time& _timeOutput,
uint32_t _nbChunk,
const etk::Vector<audio::orchestra::status>& _status)> AirTAudioCallback;
// A protected structure used for buffer conversion.
class ConvertInfo {
public:

View File

@ -9,7 +9,6 @@
#include <audio/orchestra/debug.hpp>
#include <audio/orchestra/DeviceInfo.hpp>
#include <etk/stdTools.hpp>
#include <iostream>
void audio::orchestra::DeviceInfo::display(int32_t _tabNumber) const {
etk::String space;

View File

@ -8,7 +8,6 @@
//#include <etk/types.hpp>
#include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp>
#include <iostream>
#include <audio/orchestra/api/Alsa.hpp>
#include <audio/orchestra/api/Android.hpp>
#include <audio/orchestra/api/Asio.hpp>

View File

@ -8,6 +8,7 @@
#include <etk/String.hpp>
#include <etk/Vector.hpp>
#include <etk/Pair.hpp>
#include <audio/orchestra/base.hpp>
#include <audio/orchestra/CallbackInfo.hpp>
#include <audio/orchestra/Api.hpp>
@ -183,12 +184,12 @@ namespace audio {
* when an error has occured.
*/
enum audio::orchestra::error openStream(audio::orchestra::StreamParameters *_outputParameters,
audio::orchestra::StreamParameters *_inputParameters,
enum audio::format _format,
uint32_t _sampleRate,
uint32_t* _bufferFrames,
audio::orchestra::AirTAudioCallback _callback,
const audio::orchestra::StreamOptions& _options = audio::orchestra::StreamOptions());
audio::orchestra::StreamParameters *_inputParameters,
enum audio::format _format,
uint32_t _sampleRate,
uint32_t* _bufferFrames,
audio::orchestra::AirTAudioCallback _callback,
const audio::orchestra::StreamOptions& _options = audio::orchestra::StreamOptions());
/**
* @brief A function that closes a stream and frees any associated stream memory.

View File

@ -7,6 +7,7 @@
#pragma once
#include <audio/orchestra/Flags.hpp>
#include <etk/String.hpp>
namespace audio {
namespace orchestra {

View File

@ -14,19 +14,19 @@
#include <audio/orchestra/debug.hpp>
#include <etk/stdTools.hpp>
#include <ethread/tools.hpp>
#include <climits>
#include <audio/orchestra/api/Alsa.hpp>
extern "C" {
#include <sched.h>
#include <getopt.h>
#include <sys/time.h>
#include <poll.h>
#include <sched.h>
#include <getopt.h>
#include <sys/time.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() {
return ememory::SharedPtr<audio::orchestra::api::Alsa>(new audio::orchestra::api::Alsa());
@ -39,7 +39,7 @@ namespace audio {
public:
snd_pcm_t *handle;
bool xrun[2];
std::condition_variable runnable_cv;
ethread::Semaphore m_semaphore;
bool runnable;
ethread::Thread* thread;
bool threadRunning;
@ -194,11 +194,9 @@ bool audio::orchestra::api::Alsa::getNamedDeviceInfoLocal(const etk::String& _de
}
// Test our discrete set of sample rate values.
_info.sampleRates.clear();
for (etk::Vector<uint32_t>::const_iterator it(audio::orchestra::genericSampleRate().begin());
it != audio::orchestra::genericSampleRate().end();
++it ) {
if (snd_pcm_hw_params_test_rate(phandle, params, *it, 0) == 0) {
_info.sampleRates.pushBack(*it);
for (auto &it: audio::orchestra::genericSampleRate()) {
if (snd_pcm_hw_params_test_rate(phandle, params, it, 0) == 0) {
_info.sampleRates.pushBack(it);
}
}
if (_info.sampleRates.size() == 0) {
@ -803,7 +801,7 @@ bool audio::orchestra::api::Alsa::openName(const etk::String& _deviceName,
// Setup callback thread.
m_private->threadRunning = true;
ATA_INFO("create thread ...");
m_private->thread = new ethread::Thread(&audio::orchestra::api::Alsa::alsaCallbackEvent, this);
m_private->thread = new ethread::Thread([=]() {callbackEvent();});
if (m_private->thread == nullptr) {
m_private->threadRunning = false;
ATA_ERROR("creating callback thread!");
@ -836,9 +834,9 @@ enum audio::orchestra::error audio::orchestra::api::Alsa::closeStream() {
m_mutex.lock();
if (m_state == audio::orchestra::state::stopped) {
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) {
m_private->thread->join();
m_private->thread = nullptr;
@ -865,23 +863,29 @@ enum audio::orchestra::error audio::orchestra::api::Alsa::closeStream() {
}
enum audio::orchestra::error audio::orchestra::api::Alsa::startStream() {
ATA_DEBUG("Start stream (DEGIN)");
// TODO : Check return ...
//audio::orchestra::Api::startStream();
// This method calls snd_pcm_prepare if the device isn't already in that state.
if (verifyStream() != audio::orchestra::error_none) {
ATA_WARNING("the stream not prepared!");
return audio::orchestra::error_fail;
}
if (m_state == audio::orchestra::state::running) {
ATA_ERROR("the stream is already running!");
return audio::orchestra::error_warning;
}
ATA_DEBUG("Lock");
ethread::UniqueLock lck(m_mutex);
ATA_DEBUG("Lock (done)");
int32_t result = 0;
snd_pcm_state_t state;
if (m_private->handle == nullptr) {
ATA_ERROR("send nullptr to alsa ...");
}
ATA_DEBUG("snd_pcm_state");
state = snd_pcm_state(m_private->handle);
ATA_DEBUG("snd_pcm_state (done)");
if (state != SND_PCM_STATE_PREPARED) {
ATA_ERROR("prepare stream");
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;
unlock:
m_private->runnable = true;
m_private->runnable_cv.notify_one();
m_private->m_semaphore.post();
if (result >= 0) {
ATA_DEBUG("Start stream (END2)");
return audio::orchestra::error_none;
}
ATA_DEBUG("Start stream (END)");
return audio::orchestra::error_systemError;
}
@ -950,12 +956,6 @@ unlock:
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
*/
@ -979,9 +979,8 @@ static int32_t wait_for_poll(snd_pcm_t* _handle, struct pollfd* _ufds, unsigned
void audio::orchestra::api::Alsa::callbackEvent() {
// Lock while the system is not started ...
if (m_state == audio::orchestra::state::stopped) {
ethread::UniqueLock lck(m_mutex);
while (!m_private->runnable) {
m_private->runnable_cv.wait(lck);
m_private->m_semaphore.wait();
}
if (m_state != audio::orchestra::state::running) {
return;
@ -1055,7 +1054,7 @@ audio::Time audio::orchestra::api::Alsa::getStreamTime() {
ATA_VERBOSE("snd_pcm_status_get_htstamp : " << m_startTime);
snd_pcm_sframes_t delay = snd_pcm_status_get_delay(status);
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;
if (m_mode == audio::orchestra::mode_output) {
// output
@ -1201,7 +1200,7 @@ noInput:
audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate));
audio::Duration timeProcess = stopCall - startCall;
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) {
@ -1251,7 +1250,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleWrite() {
audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate));
audio::Duration timeProcess = stopCall - startCall;
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) {
@ -1357,7 +1356,7 @@ void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPWrite() {
audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate));
audio::Duration timeProcess = stopCall - startCall;
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) {
@ -1557,7 +1556,7 @@ noInput:
audio::Duration timeDelay(0, m_bufferSize*1000000000LL/int64_t(m_sampleRate));
audio::Duration timeProcess = stopCall - startCall;
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) {

View File

@ -47,8 +47,6 @@ namespace audio {
void callbackEventOneCycleWrite();
void callbackEventOneCycleMMAPRead();
void callbackEventOneCycleMMAPWrite();
private:
static void alsaCallbackEvent(void* _userData);
private:
ememory::SharedPtr<AlsaPrivate> m_private;
etk::Vector<audio::orchestra::DeviceInfo> m_devices;

View File

@ -13,7 +13,9 @@
#include <audio/orchestra/debug.hpp>
#include <audio/orchestra/api/AndroidNativeInterface.hpp>
#include <audio/orchestra/api/Android.hpp>
#include <climits>
extern "C" {
#include <limits.h>
}
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Android::create() {
ATA_INFO("Create Android device ... ");

View File

@ -4,8 +4,10 @@
* @license APACHE v2.0 (see license file)
*/
#include <jni.h>
#include <pthread.h>
extern "C" {
#include <jni.h>
#include <pthread.h>
}
#include <ethread/Mutex.hpp>
#include <audio/orchestra/debug.hpp>
#include <audio/orchestra/error.hpp>

View File

@ -32,12 +32,13 @@ ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Asio::create()
// on information found in
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html.
#include "asiosys.h"
#include "asio.h"
#include "iasiothiscallresolver.h"
#include "asiodrivers.h"
#include <cmath>
extern "C" {
#include "asiosys.h"
#include "asio.h"
#include "iasiothiscallresolver.h"
#include "asiodrivers.h"
#include <math.h>
}
static AsioDrivers drivers;
static ASIOCallbacks asioCallbacks;
static ASIODriverInfo driverInfo;

View File

@ -37,7 +37,7 @@ namespace audio {
uint32_t nStreams[2]; // number of streams to use
bool xrun[2];
char *deviceBuffer;
std::condition_variable condition;
ethread::Semaphore m_semaphore;
int32_t drainCounter; // Tracks callback counts when draining
bool internalDrain; // Indicates if stop is initiated from callback or not.
CorePrivate() :
@ -680,11 +680,11 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream physical format for device (" << _device << ").");
return false;
}
//std::cout << "Current physical stream format:" << std::endl;
//std::cout << " mBitsPerChan = " << description.mBitsPerChannel << std::endl;
//std::cout << " aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl;
//std::cout << " bytesPerFrame = " << description.mBytesPerFrame << std::endl;
//std::cout << " sample rate = " << description.mSampleRate << std::endl;
//ATA_DEBUG("Current physical stream format:");
//ATA_DEBUG(" mBitsPerChan = " << description.mBitsPerChannel);
//ATA_DEBUG(" aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked));
//ATA_DEBUG(" bytesPerFrame = " << description.mBytesPerFrame);
//ATA_DEBUG(" sample rate = " << description.mSampleRate);
if ( description.mFormatID != kAudioFormatLinearPCM
|| description.mBitsPerChannel < 16) {
description.mFormatID = kAudioFormatLinearPCM;
@ -720,11 +720,11 @@ bool audio::orchestra::api::Core::open(uint32_t _device,
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &testDescription);
if (result == noErr) {
setPhysicalFormat = true;
//std::cout << "Updated physical stream format:" << std::endl;
//std::cout << " mBitsPerChan = " << testDescription.mBitsPerChannel << std::endl;
//std::cout << " aligned high = " << (testDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (testDescription.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl;
//std::cout << " bytesPerFrame = " << testDescription.mBytesPerFrame << std::endl;
//std::cout << " sample rate = " << testDescription.mSampleRate << std::endl;
//ATA_DEBUG("Updated physical stream format:");
//ATA_DEBUG(" mBitsPerChan = " << testDescription.mBitsPerChannel);
//ATA_DEBUG(" aligned high = " << (testDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (testDescription.mFormatFlags & kAudioFormatFlagIsPacked));
//ATA_DEBUG(" bytesPerFrame = " << testDescription.mBytesPerFrame);
//ATA_DEBUG(" sample rate = " << testDescription.mSampleRate);
break;
}
}
@ -969,7 +969,7 @@ enum audio::orchestra::error audio::orchestra::api::Core::stopStream() {
if (m_private->drainCounter == 0) {
ethread::UniqueLock lck(m_mutex);
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);
if (result != noErr) {
@ -1039,7 +1039,7 @@ bool audio::orchestra::api::Core::callbackEvent(AudioDeviceID _deviceId,
new ethread::Thread(&audio::orchestra::api::Core::coreStopStream, this);
} else {
// external call to stopStream()
m_private->condition.notify_one();
m_private->m_semaphore.post();
}
return true;
}

View File

@ -13,7 +13,9 @@
#include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp>
#include <climits>
extern "C" {
#include <limits.h>
}
#include <audio/orchestra/api/CoreIos.hpp>
ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::CoreIos::create() {
@ -132,7 +134,7 @@ void audio::orchestra::api::CoreIos::callBackEvent(void* _data,
int32_t _nbChunk,
const audio::Time& _time) {
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
|| m_mode == audio::orchestra::mode_duplex) {
if (m_doConvertBuffer[modeToIdTable(audio::orchestra::mode_output)] == true) {

View File

@ -23,11 +23,10 @@ ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Ds::create() {
// - Auto-call CoInitialize for DSOUND and ASIO platforms.
// Various revisions for RtAudio 4.0 by Gary Scavone, April 2007
// Changed device query structure for RtAudio 4.0.7, January 2010
#include <dsound.h>
#include <cassert>
#include <algorithm>
extern "C" {
#include <dsound.h>
#include <assert.h>
}
#if defined(__MINGW32__)
// missing from latest mingw winapi
#define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */
@ -377,7 +376,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Ds::getDeviceInfo(uint32_t _
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.
info.name = m_private->dsDevices[_device].name;
info.isCorrect = true;
@ -762,7 +761,7 @@ bool audio::orchestra::api::Ds::open(uint32_t _device,
// Setup the callback thread.
if (m_private->threadRunning == false) {
m_private->threadRunning = true;
ememory::SharedPtr<ethread::Thread> tmpThread(new std::thread(&audio::orchestra::api::Ds::dsCallbackEvent, this));
ememory::SharedPtr<ethread::Thread> tmpThread(new ethread::Thread([=](){audio::orchestra::api::Ds::dsCallbackEvent();});
m_private->thread = etk::move(tmpThread);
if (m_private->thread == nullptr) {
ATA_ERROR("error creating callback thread!");
@ -1154,7 +1153,7 @@ void audio::orchestra::api::Ds::callbackEvent() {
// safeWritePointer and leadPointer. If leadPointer is not
// beyond the next endWrite position, wait until it is.
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) {
leadPointer -= dsBufferSize;
}

View File

@ -7,12 +7,12 @@
// must run before :
#if defined(ORCHESTRA_BUILD_JACK)
#include <climits>
#include <iostream>
extern "C" {
#include <limits.h>
#include <string.h>
}
#include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp>
#include <cstring>
#include <ethread/tools.hpp>
#include <audio/orchestra/api/Jack.hpp>
@ -52,9 +52,9 @@ ememory::SharedPtr<audio::orchestra::Api> audio::orchestra::api::Jack::create()
// stream cannot be opened.
#include <jack/jack.h>
#include <cstdio>
extern "C" {
#include <stdio.h>
}
namespace audio {
namespace orchestra {
@ -65,7 +65,7 @@ namespace audio {
jack_port_t **ports[2];
etk::String deviceName[2];
bool xrun[2];
std::condition_variable condition;
ethread::Semaphore m_semaphore;
int32_t drainCounter; // Tracks callback counts when draining
bool internalDrain; // Indicates if stop is initiated from callback or not.
@ -113,7 +113,7 @@ uint32_t audio::orchestra::api::Jack::getDeviceCount() {
port = (char *) ports[ nChannels ];
iColon = port.find(":");
if (iColon != etk::String::npos) {
port = port.substr(0, iColon + 1);
port = port.extract(0, iColon + 1);
if (port != previousPort) {
nDevices++;
previousPort = port;
@ -121,6 +121,7 @@ uint32_t audio::orchestra::api::Jack::getDeviceCount() {
}
} while (ports[++nChannels]);
free(ports);
ports = nullptr;
}
jack_client_close(client);
return nDevices*2;
@ -150,7 +151,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Jack::getDeviceInfo(uint32_t
port = (char *) ports[nPorts];
iColon = port.find(":");
if (iColon != etk::String::npos) {
port = port.substr(0, iColon);
port = port.extract(0, iColon);
if (port != previousPort) {
if (nDevices == deviceID) {
info.name = port;
@ -223,15 +224,6 @@ int32_t audio::orchestra::api::Jack::jackCallbackHandler(jack_nframes_t _nframes
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) {
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) {
return;
}
new ethread::Thread(&audio::orchestra::api::Jack::jackCloseStream, _userData);
new ethread::Thread([=](){myClass->closeStream();});
ATA_ERROR("The Jack server is shutting down this client ... stream stopped and closed!!");
}
@ -273,7 +265,7 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
&& m_mode != audio::orchestra::mode_output)) {
jack_options_t jackoptions = (jack_options_t) (JackNoStartServer); //JackNullOption;
jack_status_t *status = nullptr;
if (!_options.streamName.empty()) {
if (_options.streamName.size() != 0) {
client = jack_client_open(_options.streamName.c_str(), jackoptions, status);
} else {
client = jack_client_open("orchestraJack", jackoptions, status);
@ -299,7 +291,7 @@ bool audio::orchestra::api::Jack::open(uint32_t _device,
port = (char *) ports[ nPorts ];
iColon = port.find(":");
if (iColon != etk::String::npos) {
port = port.substr(0, iColon);
port = port.extract(0, iColon);
if (port != previousPort) {
if (nDevices == deviceID) {
deviceName = port;
@ -597,8 +589,7 @@ enum audio::orchestra::error audio::orchestra::api::Jack::stopStream() {
|| m_mode == audio::orchestra::mode_duplex) {
if (m_private->drainCounter == 0) {
m_private->drainCounter = 2;
ethread::UniqueLock lck(m_mutex);
m_private->condition.wait(lck);
m_private->m_semaphore.wait();
}
}
jack_deactivate(m_private->client);
@ -618,17 +609,6 @@ enum audio::orchestra::error audio::orchestra::api::Jack::abortStream() {
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) {
if ( m_state == audio::orchestra::state::stopped
|| m_state == audio::orchestra::state::stopping) {
@ -646,9 +626,9 @@ bool audio::orchestra::api::Jack::callbackEvent(uint64_t _nframes) {
if (m_private->drainCounter > 3) {
m_state = audio::orchestra::state::stopping;
if (m_private->internalDrain == true) {
new ethread::Thread(jackStopStream, this);
new ethread::Thread([&](){stopStream();}, "Jack_stopStream");
} else {
m_private->condition.notify_one();
m_private->m_semaphore.post();
}
return true;
}
@ -673,7 +653,7 @@ bool audio::orchestra::api::Jack::callbackEvent(uint64_t _nframes) {
if (cbReturnValue == 2) {
m_state = audio::orchestra::state::stopping;
m_private->drainCounter = 2;
new ethread::Thread(jackStopStream, this);
new ethread::Thread([&](){stopStream();}, "Jack_stopStream2");
return true;
}
else if (cbReturnValue == 1) {

View File

@ -36,7 +36,6 @@ namespace audio {
bool callbackEvent(uint64_t _nframes);
private:
static int32_t jackXrun(void* _userData);
static void jackCloseStream(void* _userData);
static void jackShutdown(void* _userData);
static int32_t jackCallbackHandler(jack_nframes_t _nframes, void* _userData);
private:

View File

@ -8,13 +8,14 @@
#if defined(ORCHESTRA_BUILD_PULSE)
#include <climits>
extern "C" {
#include <limits.h>
#include <stdio.h>
}
#include <audio/orchestra/Interface.hpp>
#include <audio/orchestra/debug.hpp>
#include <pulse/error.h>
#include <pulse/simple.h>
#include <cstdio>
#include <ethread/tools.hpp>
#include <audio/orchestra/api/PulseDeviceList.hpp>
#include <audio/orchestra/api/Pulse.hpp>
@ -55,7 +56,7 @@ namespace audio {
pa_simple* handle;
ememory::SharedPtr<ethread::Thread> thread;
bool threadRunning;
std::condition_variable runnable_cv;
ethread::Semaphore m_semaphore;
bool runnable;
PulsePrivate() :
handle(0),
@ -96,10 +97,7 @@ audio::orchestra::DeviceInfo audio::orchestra::api::Pulse::getDeviceInfo(uint32_
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() {
ethread::setName("Pulse IO-" + m_name);
@ -113,9 +111,9 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::closeStream() {
m_mutex.lock();
if (m_state == audio::orchestra::state::stopped) {
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();
if (m_mode == audio::orchestra::mode_output) {
pa_simple_flush(m_private->handle, nullptr);
@ -131,12 +129,11 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::closeStream() {
void audio::orchestra::api::Pulse::callbackEventOneCycle() {
if (m_state == audio::orchestra::state::stopped) {
ethread::UniqueLock lck(m_mutex);
while (!m_private->runnable) {
m_private->runnable_cv.wait(lck);
m_private->m_semaphore.wait();
}
if (m_state != audio::orchestra::state::running) {
m_mutex.unlock();
m_mutex.unLock();
return;
}
}
@ -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_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) {
goto unlock;
goto unLock;
}
int32_t pa_error;
size_t bytes;
@ -194,8 +191,8 @@ void audio::orchestra::api::Pulse::callbackEventOneCycle() {
m_convertInfo[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)]);
}
}
unlock:
m_mutex.unlock();
unLock:
m_mutex.unLock();
audio::orchestra::Api::tickStreamTime();
if (doStopStream == 1) {
stopStream();
@ -218,8 +215,8 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::startStream() {
m_mutex.lock();
m_state = audio::orchestra::state::running;
m_private->runnable = true;
m_private->runnable_cv.notify_one();
m_mutex.unlock();
m_private->m_semaphore.post();
m_mutex.unLock();
return audio::orchestra::error_none;
}
@ -240,12 +237,12 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::stopStream() {
int32_t pa_error;
if (pa_simple_drain(m_private->handle, &pa_error) < 0) {
ATA_ERROR("error draining output device, " << pa_strerror(pa_error) << ".");
m_mutex.unlock();
m_mutex.unLock();
return audio::orchestra::error_systemError;
}
}
m_state = audio::orchestra::state::stopped;
m_mutex.unlock();
m_mutex.unLock();
return audio::orchestra::error_none;
}
@ -266,12 +263,12 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::abortStream() {
int32_t pa_error;
if (pa_simple_flush(m_private->handle, &pa_error) < 0) {
ATA_ERROR("error flushing output device, " << pa_strerror(pa_error) << ".");
m_mutex.unlock();
m_mutex.unLock();
return audio::orchestra::error_systemError;
}
}
m_state = audio::orchestra::state::stopped;
m_mutex.unlock();
m_mutex.unLock();
return audio::orchestra::error_none;
}
@ -393,7 +390,7 @@ bool audio::orchestra::api::Pulse::open(uint32_t _device,
}
if (m_private->threadRunning == false) {
m_private->threadRunning = true;
m_private->thread = ememory::makeShared<ethread::Thread>(&pulseaudio_callback, this);
m_private->thread = ememory::makeShared<ethread::Thread>([&](){callbackEvent();}, "pulseCallback");
if (m_private->thread == nullptr) {
ATA_ERROR("error creating thread.");
goto error;

View File

@ -6,9 +6,10 @@
*/
#if defined(ORCHESTRA_BUILD_PULSE)
#include <cstdio>
#include <cstring>
extern "C" {
#include <stdio.h>
#include <string.h>
}
#include <pulse/pulseaudio.h>
#include <audio/orchestra/api/PulseDeviceList.hpp>
#include <audio/orchestra/debug.hpp>

View File

@ -7,9 +7,9 @@
#pragma once
#include <ethread/Thread.hpp>
#include <condition_variable>
#include <ethread/Semaphore.hpp>
#include <ethread/Mutex.hpp>
#include <chrono>
#include <echrono/Steady.hpp>
#include <etk/Function.hpp>
#include <ememory/memory.hpp>
#include <audio/channel.hpp>

View File

@ -36,4 +36,4 @@ etk::Stream& audio::operator <<(etk::Stream& _os, enum audio::orchestra::mode _o
break;
}
return _os;
}
}

View File

@ -7,6 +7,7 @@
#pragma once
#include <etk/types.hpp>
#include <etk/Stream.hpp>
namespace audio {
namespace orchestra {

View File

@ -7,6 +7,7 @@
#pragma once
#include <etk/types.hpp>
#include <etk/Vector.hpp>
namespace audio {
namespace orchestra {

View File

@ -7,10 +7,6 @@
#include <audio/orchestra/type.hpp>
#include <audio/orchestra/debug.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <climits>
const etk::String audio::orchestra::typeUndefined = "undefined";
const etk::String audio::orchestra::typeAlsa = "alsa";

View File

@ -16,8 +16,8 @@ int main(int _argc, const char **_argv) {
etk::String data = _argv[iii];
if ( data == "-h"
|| data == "--help") {
std::cout << "Help : " << std::endl;
std::cout << " ./xxx ---" << std::endl;
TEST_PRINT("Help : ");
TEST_PRINT(" ./xxx ---");
exit(0);
}
}

View File

@ -16,8 +16,8 @@ int main(int _argc, const char **_argv) {
etk::String data = _argv[iii];
if ( data == "-h"
|| data == "--help") {
std::cout << "Help : " << std::endl;
std::cout << " ./xxx ---" << std::endl;
TEST_PRINT("Help : ");
TEST_PRINT(" ./xxx ---");
exit(0);
}
}

View File

@ -16,8 +16,8 @@ int main(int _argc, const char **_argv) {
etk::String data = _argv[iii];
if ( data == "-h"
|| data == "--help") {
std::cout << "Help : " << std::endl;
std::cout << " ./xxx ---" << std::endl;
TEST_PRINT("Help : ");
TEST_PRINT(" ./xxx ---");
exit(0);
}
}