[DEV] update new ETK
This commit is contained in:
parent
4bc3ff2f1a
commit
309b63254f
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <audio/orchestra/Flags.hpp>
|
||||
#include <etk/String.hpp>
|
||||
|
||||
namespace audio {
|
||||
namespace orchestra {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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 ... ");
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -36,4 +36,4 @@ etk::Stream& audio::operator <<(etk::Stream& _os, enum audio::orchestra::mode _o
|
||||
break;
|
||||
}
|
||||
return _os;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/Stream.hpp>
|
||||
|
||||
namespace audio {
|
||||
namespace orchestra {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
|
||||
namespace audio {
|
||||
namespace orchestra {
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user