mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-09-05 14:47:52 -04:00
OSX audio may be stable, works on 2010 macbook pro
This commit is contained in:
parent
7c6d2e1131
commit
ad800056d5
@ -51,8 +51,8 @@ bool CubicSDR::OnInit() {
|
|||||||
int main_policy;
|
int main_policy;
|
||||||
struct sched_param main_param;
|
struct sched_param main_param;
|
||||||
|
|
||||||
main_policy = SCHED_OTHER;
|
main_policy = SCHED_RR;
|
||||||
main_param.sched_priority = sched_get_priority_min(SCHED_OTHER);
|
main_param.sched_priority = sched_get_priority_min(SCHED_RR)+2;
|
||||||
|
|
||||||
pthread_setschedparam(pthread_self(), main_policy, &main_param);
|
pthread_setschedparam(pthread_self(), main_policy, &main_param);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define BUF_SIZE (16384*3)
|
||||||
|
#else
|
||||||
#define BUF_SIZE (16384*4)
|
#define BUF_SIZE (16384*4)
|
||||||
|
#endif
|
||||||
#define SRATE 2000000
|
#define SRATE 2000000
|
||||||
#define FFT_SIZE 2048
|
#define FFT_SIZE 2048
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
AudioThread::AudioThread(AudioThreadInputQueue *inputQueue) :
|
AudioThread::AudioThread(AudioThreadInputQueue *inputQueue) :
|
||||||
inputQueue(inputQueue), terminated(false), audio_queue_ptr(0) {
|
inputQueue(inputQueue), terminated(false), audio_queue_ptr(0), underflow_count(0) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,29 +16,63 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
|
|||||||
AudioThread *src = (AudioThread *) userData;
|
AudioThread *src = (AudioThread *) userData;
|
||||||
float *out = (float*) outputBuffer;
|
float *out = (float*) outputBuffer;
|
||||||
if (status) {
|
if (status) {
|
||||||
std::cout << "Audio buffer underflow.." << std::endl;
|
std::cout << "Audio buffer underflow.." << (src->underflow_count++) << std::endl;
|
||||||
}
|
}
|
||||||
if (!src->audio_queue.size()) {
|
|
||||||
|
std::queue<std::vector<float> > *audio_queue = src->audio_queue.load();
|
||||||
|
|
||||||
|
#ifdef __APPLE__ // Crude re-sync
|
||||||
|
int wait_for_it = 0;
|
||||||
|
|
||||||
|
if (audio_queue->empty()) {
|
||||||
|
while (wait_for_it++ < 50) { // Can we wait it out?
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(10000));
|
||||||
|
// std::this_thread::yield();
|
||||||
|
if (!audio_queue->empty()) {
|
||||||
|
std::cout << "Buffer recovery.." << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (audio_queue->empty()) {
|
||||||
for (int i = 0; i < nBufferFrames * 2; i++) {
|
for (int i = 0; i < nBufferFrames * 2; i++) {
|
||||||
out[i] = 0;
|
out[i] = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
std::vector<float> nextBuffer = src->audio_queue.front();
|
|
||||||
|
wait_for_it = 0;
|
||||||
|
|
||||||
|
std::vector<float> nextBuffer = audio_queue->front();
|
||||||
|
int nextBufferSize = nextBuffer.size();
|
||||||
for (int i = 0; i < nBufferFrames * 2; i++) {
|
for (int i = 0; i < nBufferFrames * 2; i++) {
|
||||||
out[i] = nextBuffer[src->audio_queue_ptr];
|
out[i] = nextBuffer[src->audio_queue_ptr];
|
||||||
src->audio_queue_ptr++;
|
src->audio_queue_ptr++;
|
||||||
if (src->audio_queue_ptr == nextBuffer.size()) {
|
if (src->audio_queue_ptr == nextBufferSize) {
|
||||||
src->audio_queue.pop();
|
audio_queue->pop();
|
||||||
src->audio_queue_ptr = 0;
|
src->audio_queue_ptr = 0;
|
||||||
if (!src->audio_queue.size()) {
|
if (audio_queue->empty()) {
|
||||||
for (int j = i; j < nBufferFrames * 2; j++) {
|
|
||||||
std::cout << "Audio buffer underflow.." << std::endl;
|
#ifdef __APPLE__
|
||||||
out[i] = 0;
|
while (wait_for_it++ < 50) { // Can we wait it out?
|
||||||
}
|
std::this_thread::sleep_for(std::chrono::microseconds(10000));
|
||||||
return 0;
|
if (!audio_queue->empty()) {
|
||||||
|
std::cout << "Buffer recovery.." << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (audio_queue->empty()) {
|
||||||
|
for (int j = i; j < nBufferFrames * 2; j++) {
|
||||||
|
std::cout << "Audio buffer underflow mid request.." << (src->underflow_count++) << std::endl;
|
||||||
|
out[i] = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nextBuffer = src->audio_queue.front();
|
nextBuffer = audio_queue->front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -57,12 +91,15 @@ void AudioThread::threadMain() {
|
|||||||
parameters.nChannels = 2;
|
parameters.nChannels = 2;
|
||||||
parameters.firstChannel = 0;
|
parameters.firstChannel = 0;
|
||||||
unsigned int sampleRate = AUDIO_FREQUENCY;
|
unsigned int sampleRate = AUDIO_FREQUENCY;
|
||||||
unsigned int bufferFrames = 256;
|
unsigned int bufferFrames = 0;
|
||||||
|
|
||||||
RtAudio::StreamOptions opts;
|
RtAudio::StreamOptions opts;
|
||||||
opts.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME;
|
// opts.flags = RTAUDIO_SCHEDULE_REALTIME | RTAUDIO_MINIMIZE_LATENCY;
|
||||||
|
// opts.flags = RTAUDIO_MINIMIZE_LATENCY;
|
||||||
opts.streamName = "CubicSDR Audio Output";
|
opts.streamName = "CubicSDR Audio Output";
|
||||||
opts.priority = 0;
|
opts.priority = sched_get_priority_max(SCHED_FIFO);
|
||||||
|
|
||||||
|
audio_queue = new std::queue<std::vector<float> >;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dac.openStream(¶meters, NULL, RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &audioCallback, (void *) this, &opts);
|
dac.openStream(¶meters, NULL, RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &audioCallback, (void *) this, &opts);
|
||||||
@ -74,10 +111,11 @@ void AudioThread::threadMain() {
|
|||||||
|
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
AudioThreadInput inp;
|
AudioThreadInput inp;
|
||||||
inputQueue->pop(inp);
|
inputQueue->pop(inp);
|
||||||
if (inp.data.size()) {
|
if (inp.data.size()) {
|
||||||
audio_queue.push(inp.data);
|
audio_queue.load()->push(inp.data);
|
||||||
}
|
}
|
||||||
|
// std::this_thread::yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -28,8 +28,9 @@ typedef ThreadQueue<AudioThreadInput> AudioThreadInputQueue;
|
|||||||
|
|
||||||
class AudioThread {
|
class AudioThread {
|
||||||
public:
|
public:
|
||||||
std::queue<std::vector<float> > audio_queue;
|
std::atomic< std::queue<std::vector<float> > *> audio_queue;
|
||||||
unsigned int audio_queue_ptr;
|
std::atomic<unsigned int> audio_queue_ptr;
|
||||||
|
std::atomic<unsigned int> underflow_count;
|
||||||
|
|
||||||
AudioThread(AudioThreadInputQueue *inputQueue);
|
AudioThread(AudioThreadInputQueue *inputQueue);
|
||||||
~AudioThread();
|
~AudioThread();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user