mirror of https://github.com/AxioDL/boo.git
AudioQueueServices fix
This commit is contained in:
parent
1b3209f4bf
commit
0dfab1fdad
2
glslang
2
glslang
|
@ -1 +1 @@
|
||||||
Subproject commit cb9c7d7bd57c09fd73c5aadfc881c0140b64fcdb
|
Subproject commit 9bfc3ae1c149bb8272af3809099fff78ce780cd8
|
|
@ -37,7 +37,7 @@ struct AQSAudioVoice : IAudioVoice
|
||||||
IAudioVoiceCallback* m_cb;
|
IAudioVoiceCallback* m_cb;
|
||||||
AudioQueueRef m_queue = nullptr;
|
AudioQueueRef m_queue = nullptr;
|
||||||
AudioQueueBufferRef m_buffers[3];
|
AudioQueueBufferRef m_buffers[3];
|
||||||
size_t m_bufferFrames = 2048;
|
size_t m_bufferFrames = 1024;
|
||||||
size_t m_frameSize;
|
size_t m_frameSize;
|
||||||
|
|
||||||
const ChannelMap& channelMap() const {return m_map;}
|
const ChannelMap& channelMap() const {return m_map;}
|
||||||
|
@ -48,7 +48,7 @@ struct AQSAudioVoice : IAudioVoice
|
||||||
{
|
{
|
||||||
AQSAudioVoice* voice = static_cast<AQSAudioVoice*>(inUserData);
|
AQSAudioVoice* voice = static_cast<AQSAudioVoice*>(inUserData);
|
||||||
voice->m_callbackBuf = inBuffer;
|
voice->m_callbackBuf = inBuffer;
|
||||||
voice->m_cb->needsNextBuffer(voice, voice->m_bufferFrames);
|
voice->m_cb->needsNextBuffer(*voice, voice->m_bufferFrames);
|
||||||
voice->m_callbackBuf = nullptr;
|
voice->m_callbackBuf = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,15 +80,17 @@ struct AQSAudioVoice : IAudioVoice
|
||||||
}
|
}
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Error, "unable to create output audio queue");
|
Log.report(logvisor::Fatal, "unable to create output audio queue");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chCount > 2)
|
||||||
|
{
|
||||||
AudioChannelLayout layout;
|
AudioChannelLayout layout;
|
||||||
UInt32 layoutSz = sizeof(layout);
|
UInt32 layoutSz = sizeof(layout);
|
||||||
if (AudioQueueGetProperty(m_queue, kAudioQueueProperty_ChannelLayout, &layout, &layoutSz))
|
if (AudioQueueGetProperty(m_queue, kAudioQueueProperty_ChannelLayout, &layout, &layoutSz))
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Error, "unable to get channel layout from audio queue");
|
Log.report(logvisor::Fatal, "unable to get channel layout from audio queue");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,12 +144,18 @@ struct AQSAudioVoice : IAudioVoice
|
||||||
m_map.m_channels[4] = AudioChannel::FrontCenter;
|
m_map.m_channels[4] = AudioChannel::FrontCenter;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.report(logvisor::Error, "unknown channel layout %u; using stereo", layout.mChannelLayoutTag);
|
Log.report(logvisor::Fatal, "unknown channel layout %u; using stereo", layout.mChannelLayoutTag);
|
||||||
m_map.m_channelCount = 2;
|
m_map.m_channelCount = 2;
|
||||||
m_map.m_channels[0] = AudioChannel::FrontLeft;
|
m_map.m_channels[0] = AudioChannel::FrontLeft;
|
||||||
m_map.m_channels[1] = AudioChannel::FrontRight;
|
m_map.m_channels[1] = AudioChannel::FrontRight;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_map.m_channels[m_map.m_channelCount++] = AudioChannel::FrontLeft;
|
||||||
|
m_map.m_channels[m_map.m_channelCount++] = AudioChannel::FrontRight;
|
||||||
|
}
|
||||||
|
|
||||||
while (m_map.m_channelCount < chCount)
|
while (m_map.m_channelCount < chCount)
|
||||||
m_map.m_channels[m_map.m_channelCount++] = AudioChannel::Unknown;
|
m_map.m_channels[m_map.m_channelCount++] = AudioChannel::Unknown;
|
||||||
|
@ -155,7 +163,7 @@ struct AQSAudioVoice : IAudioVoice
|
||||||
for (int i=0 ; i<3 ; ++i)
|
for (int i=0 ; i<3 ; ++i)
|
||||||
if (AudioQueueAllocateBuffer(m_queue, m_bufferFrames * chCount * 2, &m_buffers[i]))
|
if (AudioQueueAllocateBuffer(m_queue, m_bufferFrames * chCount * 2, &m_buffers[i]))
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Error, "unable to create audio queue buffer");
|
Log.report(logvisor::Fatal, "unable to create audio queue buffer");
|
||||||
AudioQueueDispose(m_queue, false);
|
AudioQueueDispose(m_queue, false);
|
||||||
m_queue = nullptr;
|
m_queue = nullptr;
|
||||||
return;
|
return;
|
||||||
|
@ -166,7 +174,7 @@ struct AQSAudioVoice : IAudioVoice
|
||||||
for (unsigned i=0 ; i<3 ; ++i)
|
for (unsigned i=0 ; i<3 ; ++i)
|
||||||
{
|
{
|
||||||
m_primeBuf = i;
|
m_primeBuf = i;
|
||||||
m_cb->needsNextBuffer(this, m_bufferFrames);
|
m_cb->needsNextBuffer(*this, m_bufferFrames);
|
||||||
}
|
}
|
||||||
AudioQueuePrime(m_queue, 0, nullptr);
|
AudioQueuePrime(m_queue, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
@ -206,6 +214,56 @@ struct AQSAudioVoice : IAudioVoice
|
||||||
|
|
||||||
struct AQSAudioVoiceAllocator : IAudioVoiceAllocator
|
struct AQSAudioVoiceAllocator : IAudioVoiceAllocator
|
||||||
{
|
{
|
||||||
|
static void DummyCallback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {}
|
||||||
|
|
||||||
|
AudioChannelSet getAvailableSet()
|
||||||
|
{
|
||||||
|
const unsigned chCount = 8;
|
||||||
|
AudioStreamBasicDescription desc = {};
|
||||||
|
desc.mSampleRate = 32000;
|
||||||
|
desc.mFormatID = kAudioFormatLinearPCM;
|
||||||
|
desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||||
|
desc.mBytesPerPacket = chCount * 2;
|
||||||
|
desc.mFramesPerPacket = 1;
|
||||||
|
desc.mBytesPerFrame = chCount * 2;
|
||||||
|
desc.mChannelsPerFrame = chCount;
|
||||||
|
desc.mBitsPerChannel = 16;
|
||||||
|
|
||||||
|
AudioQueueRef queue;
|
||||||
|
if (AudioQueueNewOutput(&desc, AudioQueueOutputCallback(DummyCallback),
|
||||||
|
this, nullptr, nullptr, 0, &queue))
|
||||||
|
{
|
||||||
|
Log.report(logvisor::Error, "unable to create output audio queue");
|
||||||
|
return AudioChannelSet::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 hwChannels;
|
||||||
|
UInt32 channelsSz = sizeof(UInt32);
|
||||||
|
if (AudioQueueGetProperty(queue, kAudioQueueDeviceProperty_NumberChannels, &hwChannels, &channelsSz))
|
||||||
|
{
|
||||||
|
Log.report(logvisor::Error, "unable to get channel count from audio queue");
|
||||||
|
AudioQueueDispose(queue, true);
|
||||||
|
return AudioChannelSet::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioQueueDispose(queue, true);
|
||||||
|
|
||||||
|
switch (hwChannels)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
return AudioChannelSet::Stereo;
|
||||||
|
case 4:
|
||||||
|
return AudioChannelSet::Quad;
|
||||||
|
case 6:
|
||||||
|
return AudioChannelSet::Surround51;
|
||||||
|
case 8:
|
||||||
|
return AudioChannelSet::Surround71;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AudioChannelSet::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<IAudioVoice> allocateNewVoice(AudioChannelSet layoutOut,
|
std::unique_ptr<IAudioVoice> allocateNewVoice(AudioChannelSet layoutOut,
|
||||||
unsigned sampleRate,
|
unsigned sampleRate,
|
||||||
IAudioVoiceCallback* cb)
|
IAudioVoiceCallback* cb)
|
||||||
|
@ -216,6 +274,8 @@ struct AQSAudioVoiceAllocator : IAudioVoiceAllocator
|
||||||
return {};
|
return {};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pumpVoices() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IAudioVoiceAllocator> NewAudioVoiceAllocator()
|
std::unique_ptr<IAudioVoiceAllocator> NewAudioVoiceAllocator()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "../mac/CocoaCommon.hpp"
|
#include "../mac/CocoaCommon.hpp"
|
||||||
#if BOO_HAS_METAL
|
#if BOO_HAS_METAL
|
||||||
#include <LogVisor/LogVisor.hpp>
|
#include "logvisor/logvisor.hpp"
|
||||||
#include "boo/graphicsdev/Metal.hpp"
|
#include "boo/graphicsdev/Metal.hpp"
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("boo::Metal");
|
static logvisor::Module Log("boo::Metal");
|
||||||
struct MetalCommandQueue;
|
struct MetalCommandQueue;
|
||||||
|
|
||||||
ThreadLocalPtr<struct MetalData> MetalDataFactory::m_deferredData;
|
ThreadLocalPtr<struct MetalData> MetalDataFactory::m_deferredData;
|
||||||
|
@ -198,7 +198,7 @@ class MetalTextureD : public ITextureD
|
||||||
m_pxPitch = 1;
|
m_pxPitch = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.report(LogVisor::FatalError, "unsupported tex format");
|
Log.report(logvisor::Fatal, "unsupported tex format");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cpuSz = width * height * m_pxPitch;
|
m_cpuSz = width * height * m_pxPitch;
|
||||||
|
@ -444,7 +444,7 @@ class MetalShaderPipeline : public IShaderPipeline
|
||||||
NSError* err = nullptr;
|
NSError* err = nullptr;
|
||||||
m_state = [ctx->m_dev newRenderPipelineStateWithDescriptor:desc error:&err];
|
m_state = [ctx->m_dev newRenderPipelineStateWithDescriptor:desc error:&err];
|
||||||
if (err)
|
if (err)
|
||||||
Log.report(LogVisor::FatalError, "error making shader pipeline: %s",
|
Log.report(logvisor::Fatal, "error making shader pipeline: %s",
|
||||||
[[err localizedDescription] UTF8String]);
|
[[err localizedDescription] UTF8String]);
|
||||||
|
|
||||||
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new];
|
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new];
|
||||||
|
@ -962,14 +962,14 @@ IShaderPipeline* MetalDataFactory::newShaderPipeline(const char* vertSource, con
|
||||||
options:compOpts
|
options:compOpts
|
||||||
error:&err];
|
error:&err];
|
||||||
if (err)
|
if (err)
|
||||||
Log.report(LogVisor::FatalError, "error compiling vert shader: %s", [[err localizedDescription] UTF8String]);
|
Log.report(logvisor::Fatal, "error compiling vert shader: %s", [[err localizedDescription] UTF8String]);
|
||||||
id<MTLFunction> vertFunc = [vertShaderLib newFunctionWithName:@"vmain"];
|
id<MTLFunction> vertFunc = [vertShaderLib newFunctionWithName:@"vmain"];
|
||||||
|
|
||||||
id<MTLLibrary> fragShaderLib = [m_ctx->m_dev newLibraryWithSource:@(fragSource)
|
id<MTLLibrary> fragShaderLib = [m_ctx->m_dev newLibraryWithSource:@(fragSource)
|
||||||
options:compOpts
|
options:compOpts
|
||||||
error:&err];
|
error:&err];
|
||||||
if (err)
|
if (err)
|
||||||
Log.report(LogVisor::FatalError, "error compiling frag shader: %s", [[err localizedDescription] UTF8String]);
|
Log.report(logvisor::Fatal, "error compiling frag shader: %s", [[err localizedDescription] UTF8String]);
|
||||||
id<MTLFunction> fragFunc = [fragShaderLib newFunctionWithName:@"fmain"];
|
id<MTLFunction> fragFunc = [fragShaderLib newFunctionWithName:@"fmain"];
|
||||||
|
|
||||||
MetalShaderPipeline* retval = new MetalShaderPipeline(m_ctx, vertFunc, fragFunc,
|
MetalShaderPipeline* retval = new MetalShaderPipeline(m_ctx, vertFunc, fragFunc,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "boo/graphicsdev/Metal.hpp"
|
#include "boo/graphicsdev/Metal.hpp"
|
||||||
#include "CocoaCommon.hpp"
|
#include "CocoaCommon.hpp"
|
||||||
|
|
||||||
#include <LogVisor/LogVisor.hpp>
|
#include "logvisor/logvisor.hpp"
|
||||||
|
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
#error ARC Required
|
#error ARC Required
|
||||||
|
@ -22,7 +22,7 @@ namespace boo {class ApplicationCocoa;}
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("boo::ApplicationCocoa");
|
static logvisor::Module Log("boo::ApplicationCocoa");
|
||||||
|
|
||||||
IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx,
|
IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx,
|
||||||
MetalContext* metalCtx, uint32_t sampleCount);
|
MetalContext* metalCtx, uint32_t sampleCount);
|
||||||
|
@ -91,11 +91,11 @@ public:
|
||||||
{
|
{
|
||||||
m_metalCtx.m_dev = MTLCreateSystemDefaultDevice();
|
m_metalCtx.m_dev = MTLCreateSystemDefaultDevice();
|
||||||
m_metalCtx.m_q = [m_metalCtx.m_dev newCommandQueue];
|
m_metalCtx.m_q = [m_metalCtx.m_dev newCommandQueue];
|
||||||
Log.report(LogVisor::Info, "using Metal renderer");
|
Log.report(logvisor::Info, "using Metal renderer");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!m_metalCtx.m_dev)
|
if (!m_metalCtx.m_dev)
|
||||||
Log.report(LogVisor::Info, "using OpenGL renderer");
|
Log.report(logvisor::Info, "using OpenGL renderer");
|
||||||
#else
|
#else
|
||||||
Log.report(LogVisor::Info, "using OpenGL renderer");
|
Log.report(LogVisor::Info, "using OpenGL renderer");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -165,7 +165,7 @@ class GraphicsContextCocoaMetal;
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("boo::WindowCocoa");
|
static logvisor::Module Log("boo::WindowCocoa");
|
||||||
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent);
|
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent);
|
||||||
IGraphicsCommandQueue* _NewMetalCommandQueue(MetalContext* ctx, IWindow* parentWindow,
|
IGraphicsCommandQueue* _NewMetalCommandQueue(MetalContext* ctx, IWindow* parentWindow,
|
||||||
IGraphicsContext* parent);
|
IGraphicsContext* parent);
|
||||||
|
@ -223,7 +223,7 @@ public:
|
||||||
{
|
{
|
||||||
m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this];
|
m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this];
|
||||||
if (!m_nsContext)
|
if (!m_nsContext)
|
||||||
Log.report(LogVisor::FatalError, "unable to make new NSOpenGLView");
|
Log.report(logvisor::Fatal, "unable to make new NSOpenGLView");
|
||||||
[(__bridge NSWindow*)(void*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext];
|
[(__bridge NSWindow*)(void*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext];
|
||||||
CVDisplayLinkCreateWithActiveCGDisplays(&m_dispLink);
|
CVDisplayLinkCreateWithActiveCGDisplays(&m_dispLink);
|
||||||
CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this);
|
CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this);
|
||||||
|
@ -257,7 +257,7 @@ public:
|
||||||
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[int(m_pf)]];
|
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[int(m_pf)]];
|
||||||
m_mainCtx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:[m_nsContext openGLContext]];
|
m_mainCtx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:[m_nsContext openGLContext]];
|
||||||
if (!m_mainCtx)
|
if (!m_mainCtx)
|
||||||
Log.report(LogVisor::FatalError, "unable to make main NSOpenGLContext");
|
Log.report(logvisor::Fatal, "unable to make main NSOpenGLContext");
|
||||||
}
|
}
|
||||||
[m_mainCtx makeCurrentContext];
|
[m_mainCtx makeCurrentContext];
|
||||||
return m_dataFactory;
|
return m_dataFactory;
|
||||||
|
@ -270,7 +270,7 @@ public:
|
||||||
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[int(m_pf)]];
|
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[int(m_pf)]];
|
||||||
m_loadCtx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:[m_nsContext openGLContext]];
|
m_loadCtx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:[m_nsContext openGLContext]];
|
||||||
if (!m_loadCtx)
|
if (!m_loadCtx)
|
||||||
Log.report(LogVisor::FatalError, "unable to make load NSOpenGLContext");
|
Log.report(logvisor::Fatal, "unable to make load NSOpenGLContext");
|
||||||
}
|
}
|
||||||
[m_loadCtx makeCurrentContext];
|
[m_loadCtx makeCurrentContext];
|
||||||
return m_dataFactory;
|
return m_dataFactory;
|
||||||
|
@ -380,7 +380,7 @@ public:
|
||||||
MetalContext::Window& w = m_metalCtx->m_windows[m_parentWindow];
|
MetalContext::Window& w = m_metalCtx->m_windows[m_parentWindow];
|
||||||
m_nsContext = [[GraphicsContextCocoaMetalInternal alloc] initWithBooContext:this];
|
m_nsContext = [[GraphicsContextCocoaMetalInternal alloc] initWithBooContext:this];
|
||||||
if (!m_nsContext)
|
if (!m_nsContext)
|
||||||
Log.report(LogVisor::FatalError, "unable to make new NSView for Metal");
|
Log.report(logvisor::Fatal, "unable to make new NSView for Metal");
|
||||||
w.m_metalLayer = (CAMetalLayer*)m_nsContext.layer;
|
w.m_metalLayer = (CAMetalLayer*)m_nsContext.layer;
|
||||||
[(__bridge NSWindow*)(void*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext];
|
[(__bridge NSWindow*)(void*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext];
|
||||||
CVDisplayLinkCreateWithActiveCGDisplays(&m_dispLink);
|
CVDisplayLinkCreateWithActiveCGDisplays(&m_dispLink);
|
||||||
|
|
Loading…
Reference in New Issue