this repo has no description
at fixPythonPipStalling 130 lines 5.3 kB view raw
1/* 2This file is part of Darling. 3 4Copyright (C) 2020 Lubos Dolezel 5 6Darling is free software: you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation, either version 3 of the License, or 9(at your option) any later version. 10 11Darling is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with Darling. If not, see <http://www.gnu.org/licenses/>. 18*/ 19 20#include "AudioConverter.h" 21#include "AudioConverterImpl.h" 22#include <CarbonCore/MacErrors.h> 23#include <stdexcept> 24#include <cstring> 25 26OSStatus AudioConverterNew(const AudioStreamBasicDescription* inSourceFormat, const AudioStreamBasicDescription* inDestinationFormat, AudioConverterRef* outAudioConverter) 27{ 28 return AudioConverter::create(inSourceFormat, inDestinationFormat, (AudioConverter**)outAudioConverter); 29} 30 31OSStatus AudioConverterNewSpecific(const AudioStreamBasicDescription* inSourceFormat, const AudioStreamBasicDescription* inDestinationFormat, UInt32 inNumberClassDescriptions, AudioClassDescription* nClassDescriptions, AudioConverterRef* outAudioConverter) 32{ 33 // FIXME 34 return AudioConverterNew(inSourceFormat, inDestinationFormat, outAudioConverter); 35} 36 37OSStatus AudioConverterReset(AudioConverterRef inAudioConverter) 38{ 39 if (inAudioConverter) 40 { 41 ((AudioConverter*)inAudioConverter)->flush(); 42 return noErr; 43 } 44 else 45 return paramErr; 46} 47 48OSStatus AudioConverterDispose(AudioConverterRef inAudioConverter) 49{ 50 delete (AudioConverter*)inAudioConverter; 51 return noErr; 52} 53 54OSStatus AudioConverterGetProperty(AudioConverterRef inAudioConverter, AudioConverterPropertyID inPropertyID, UInt32 *ioPropertyDataSize, void *outPropertyData) 55{ 56 return ((AudioConverter*)inAudioConverter)->getProperty(inPropertyID, ioPropertyDataSize, outPropertyData); 57} 58 59OSStatus AudioConverterGetPropertyInfo(AudioConverterRef inAudioConverter, AudioConverterPropertyID inPropertyID, UInt32 *outSize, Boolean *outWritable) 60{ 61 return ((AudioConverter*)inAudioConverter)->getPropertyInfo(inPropertyID, outSize, outWritable); 62} 63 64OSStatus AudioConverterSetProperty(AudioConverterRef inAudioConverter, AudioConverterPropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData) 65{ 66 return ((AudioConverter*)inAudioConverter)->setProperty(inPropertyID, inPropertyDataSize, inPropertyData); 67} 68 69OSStatus AudioConverterConvertBuffer(AudioConverterRef inAudioConverter, UInt32 inInputDataSize, const void* inInputData, UInt32 *ioOutputDataSize, void *outOutputData) 70{ 71 AudioBufferList in, out; 72 OSStatus stat; 73 74 in.mNumberBuffers = out.mNumberBuffers = 1; 75 76 in.mBuffers[0].mNumberChannels = 2; 77 out.mBuffers[0].mNumberChannels = 2; 78 79 in.mBuffers[0].mDataByteSize = inInputDataSize; 80 in.mBuffers[0].mData = const_cast<void*>(inInputData); 81 82 out.mBuffers[0].mDataByteSize = *ioOutputDataSize; 83 out.mBuffers[0].mData = outOutputData; 84 85 stat = AudioConverterConvertComplexBuffer(inAudioConverter, inInputDataSize/((AudioConverter*)inAudioConverter)->frameSize(), &in, &out); 86 *ioOutputDataSize = out.mBuffers[0].mDataByteSize; 87 88 return stat; 89} 90 91OSStatus AudioConverterFillComplexBuffer(AudioConverterRef inAudioConverter, AudioConverterComplexInputDataProc inInputDataProc, void *inInputDataProcUserData, UInt32 *ioOutputDataPacketSize, AudioBufferList *outOutputData, AudioStreamPacketDescription* outPacketDescription) 92{ 93 return ((AudioConverter*)inAudioConverter)->fillComplex(inInputDataProc, inInputDataProcUserData, ioOutputDataPacketSize, outOutputData, outPacketDescription); 94} 95 96OSStatus AudioConverterConvertComplexBuffer(AudioConverterRef inAudioConverter, UInt32 inNumberPCMFrames, const AudioBufferList *inInputData, AudioBufferList *outOutputData) 97{ 98 OSStatus status; 99 UInt32 dataPacketSize; 100 int64_t totalOutBytes = 0; 101 typedef OSStatus (^CallbackBlock)(AudioConverterRef audioConverter, UInt32* numberDataPackets, AudioBufferList* data, AudioStreamPacketDescription** dataPacketDescription); 102 103 CallbackBlock callbackBlock = 104 ^ OSStatus (AudioConverterRef audioConverter, UInt32* numberDataPackets, AudioBufferList* data, AudioStreamPacketDescription** dataPacketDescription) 105 { 106 const AudioBufferList *inInputData = (AudioBufferList*) inInputData; 107 108 if (dataPacketDescription) 109 *dataPacketDescription = nullptr; 110 111 // TODO 112 113 return unimpErr; 114 }; 115 116 // Squeezing a block through a function pointer 117 AudioConverterComplexInputDataProc proc = [](AudioConverterRef audioConverter, UInt32* numberDataPackets, AudioBufferList* data, AudioStreamPacketDescription** dataPacketDescription, void* userData) -> OSStatus 118 { 119 CallbackBlock callbackBlock = (CallbackBlock) userData; 120 return callbackBlock(audioConverter, numberDataPackets, data, dataPacketDescription); 121 }; 122 123 for (UInt32 i = 0; i < outOutputData->mNumberBuffers; i++) 124 totalOutBytes += outOutputData->mBuffers[i].mDataByteSize; 125 126 dataPacketSize = totalOutBytes / ((AudioConverter*)inAudioConverter)->frameSize(); 127 128 status = AudioConverterFillComplexBuffer(inAudioConverter, proc, (void*) inInputData, &dataPacketSize, outOutputData, nullptr); 129 return status; 130}