this repo has no description
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}