From 20ab3deedbba70d778a0f87ccddb53896ed50718 Mon Sep 17 00:00:00 2001 From: Johannes Pohl Date: Tue, 13 Sep 2016 14:49:20 +0200 Subject: [PATCH] basic coreAudio playback is working --- client/controller.cpp | 2 +- client/player/coreAudioPlayer.cpp | 76 ++++++++++++++++++++++++++++--- client/player/coreAudioPlayer.h | 11 ++++- common/timeDefs.h | 2 +- 4 files changed, 81 insertions(+), 10 deletions(-) diff --git a/client/controller.cpp b/client/controller.cpp index dbd7d302..4352d3f7 100644 --- a/client/controller.cpp +++ b/client/controller.cpp @@ -119,7 +119,7 @@ void Controller::onMessageReceived(ClientConnection* connection, const msg::Base #elif HAS_COREAUDIO player_.reset(new CoreAudioPlayer(pcmDevice_, stream_.get())); #else - throw SnapException("No ALSA or OPENSL support"); + throw SnapException("No audio player support"); #endif player_->setVolume(serverSettings_->getVolume() / 100.); player_->setMute(serverSettings_->isMuted()); diff --git a/client/player/coreAudioPlayer.cpp b/client/player/coreAudioPlayer.cpp index 6413b032..b07120ac 100644 --- a/client/player/coreAudioPlayer.cpp +++ b/client/player/coreAudioPlayer.cpp @@ -18,9 +18,7 @@ #include -#include -#include -#include + #include "coreAudioPlayer.h" @@ -28,8 +26,17 @@ //http://stackoverflow.com/questions/4863811/how-to-use-audioqueue-to-play-a-sound-for-mac-osx-in-c //https://gist.github.com/andormade/1360885 +void callback(void *custom_data, AudioQueueRef queue, AudioQueueBufferRef buffer) +{ + CoreAudioPlayer* player = static_cast(custom_data); + player->playerCallback(queue, buffer); +} -CoreAudioPlayer::CoreAudioPlayer(const PcmDevice& pcmDevice, Stream* stream) : Player(pcmDevice, stream) + +CoreAudioPlayer::CoreAudioPlayer(const PcmDevice& pcmDevice, Stream* stream) : + Player(pcmDevice, stream), + ms_(50), + pubStream_(stream) { } @@ -39,12 +46,67 @@ CoreAudioPlayer::~CoreAudioPlayer() } -void CoreAudioPlayer::worker() +void CoreAudioPlayer::playerCallback(AudioQueueRef queue, AudioQueueBufferRef bufferRef) { - while (active_) +//logO << "Callback\n"; + chronos::usec delay(ms_ * 1000); + char *buffer = (char*)bufferRef->mAudioData; + if (!pubStream_->getPlayerChunk(buffer, delay, frames_)) { - usleep(100*1000); + logO << "Failed to get chunk. Playing silence.\n"; + memset(buffer, 0, buff_size_); } + else + { + adjustVolume(buffer, frames_); + } + +// OSStatus status = + AudioQueueEnqueueBuffer(queue, bufferRef, 0, NULL); + + if (!active_) + { + AudioQueueStop(queue, false); + AudioQueueDispose(queue, false); + CFRunLoopStop(CFRunLoopGetCurrent()); + } } +void CoreAudioPlayer::worker() +{ + AudioStreamBasicDescription format; + AudioQueueRef queue; + AudioQueueBufferRef buffers[2]; + + const SampleFormat& sampleFormat = pubStream_->getFormat(); + + format.mSampleRate = sampleFormat.rate; + format.mFormatID = kAudioFormatLinearPCM; + format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;// | kAudioFormatFlagIsPacked; + format.mBitsPerChannel = sampleFormat.bits; + format.mChannelsPerFrame = sampleFormat.channels; + format.mBytesPerFrame = sampleFormat.frameSize; + format.mFramesPerPacket = 1; + format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket; + format.mReserved = 0; + + AudioQueueNewOutput(&format, callback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &queue); + + frames_ = (sampleFormat.rate * ms_) / 1000; + ms_ = frames_ * 1000 / sampleFormat.rate; + logO << "frames: " << frames_ << ", ms: " << ms_ << "\n"; + buff_size_ = frames_ * sampleFormat.frameSize; + + for (int i = 0; i < 2; i++) + { + AudioQueueAllocateBuffer(queue, buff_size_, &buffers[i]); + buffers[i]->mAudioDataByteSize = buff_size_; + callback(this, queue, buffers[i]); + } + + logE << "CoreAudioPlayer::worker\n"; + AudioQueueStart(queue, NULL); + CFRunLoopRun(); +} + diff --git a/client/player/coreAudioPlayer.h b/client/player/coreAudioPlayer.h index 6b8a350e..99b1ad32 100644 --- a/client/player/coreAudioPlayer.h +++ b/client/player/coreAudioPlayer.h @@ -19,8 +19,11 @@ #ifndef CORE_AUDIO_PLAYER_H #define CORE_AUDIO_PLAYER_H -#include "player.h" +#include +#include +#include +#include "player.h" /// Audio Player /** @@ -32,9 +35,15 @@ public: CoreAudioPlayer(const PcmDevice& pcmDevice, Stream* stream); virtual ~CoreAudioPlayer(); + void playerCallback(AudioQueueRef queue, AudioQueueBufferRef bufferRef); + protected: virtual void worker(); + size_t ms_; + size_t frames_; + size_t buff_size_; + Stream* pubStream_; }; diff --git a/common/timeDefs.h b/common/timeDefs.h index 2e021c98..02905026 100644 --- a/common/timeDefs.h +++ b/common/timeDefs.h @@ -24,7 +24,7 @@ namespace chronos { - typedef std::chrono::high_resolution_clock hrc; + typedef std::chrono::system_clock hrc; typedef std::chrono::time_point time_point_hrc; typedef std::chrono::seconds sec; typedef std::chrono::milliseconds msec;