1 /*
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include "AVFKernelProcessor.h"
27
28 #include <pthread.h>
29
30 // Apple reserves 0-1024 for their own properties
31 #define kAVFProperty_KernelProcessor 2099
32
33 class AVFKernelComponent : AUEffectBase {
34 public:
35 AVFKernelComponent(AudioComponentInstance audioUnit, bool inProcessesInPlace = true)
36 : AUEffectBase(audioUnit, inProcessesInPlace),
37 mUsesKernel(false),
38 mProcessor(NULL)
39 {}
40
41 virtual ~AVFKernelComponent() {
42 // Don't do anything with mProcessor as it could have been deleted already
43 }
44
45 virtual AUKernelBase *NewKernel() {
46 if (mProcessor) {
47 AUKernelBase *kernel = mProcessor->NewKernel();
48 mUsesKernel = (kernel != NULL);
49 return kernel;
50 }
51 mUsesKernel = false;
52 return NULL;
53 }
54
55 virtual OSStatus ChangeStreamFormat(AudioUnitScope inScope,
56 AudioUnitElement inElement,
57 const CAStreamBasicDescription &inPrevFormat,
58 const CAStreamBasicDescription &inNewFormat) {
59 OSStatus status = this->AUEffectBase::ChangeStreamFormat(inScope,
60 inElement,
61 inPrevFormat,
62 inNewFormat);
63 if (inScope == kAudioUnitScope_Input && inElement == 0) {
64 mProcessor->StreamFormatChanged(inNewFormat);
65 }
66 return status;
67 }
68
69 virtual OSStatus ProcessBufferLists(AudioUnitRenderActionFlags& ioActionFlags,
70 const AudioBufferList& inBuffer,
71 AudioBufferList& outBuffer,
72 UInt32 inFramesToProcess) {
73 // Call our base class if we have kernels
74 if (mUsesKernel) {
75 return this->AUEffectBase::ProcessBufferLists(ioActionFlags,
76 inBuffer,
77 outBuffer,
78 inFramesToProcess);
79 }
80 // Otherwise call ProcessBufferLists
81 if (mProcessor) {
82 return mProcessor->ProcessBufferLists(ioActionFlags,
83 inBuffer,
84 outBuffer,
85 inFramesToProcess);
86 }
87 return noErr; // ??? just in case
88 }
89
90 virtual OSStatus SetProperty(AudioUnitPropertyID inID,
91 AudioUnitScope inScope,
92 AudioUnitElement inElement,
93 const void *inData,
94 UInt32 inDataSize) {
95 if (inID == kAVFProperty_KernelProcessor &&
96 inScope == kAudioUnitScope_Global &&
97 inElement == 0) {
98 if (inDataSize == sizeof(AVFKernelProcessor*)) {
99 AVFKernelProcessor *processor = *((AVFKernelProcessor **)inData);
100 if (mProcessor != processor) {
101 if (mProcessor) {
102 mProcessor->SetAudioUnit(NULL);
103 mProcessor = NULL;
104 }
105
106 mProcessor = processor;
107 if (mProcessor) {
108 mProcessor->SetAudioUnit(this);
109 const AudioStreamBasicDescription& format =
110 GetStreamFormat(kAudioUnitScope_Input, 0);
111 mProcessor->StreamFormatChanged(format);
112 }
113 }
114 return noErr;
115 }
116 return kAudioUnitErr_InvalidPropertyValue;
117 }
118 return this->AUEffectBase::SetProperty(inID, inScope, inElement, inData, inDataSize);
119 }
120 private:
121 bool mUsesKernel;
122 AVFKernelProcessor *mProcessor;
123 };
124
125 // Synchronize registration of the component
126 volatile AudioComponent gAVFComponent = NULL;
127 pthread_mutex_t gAVFComponentLock = PTHREAD_MUTEX_INITIALIZER;
128
129 static inline AudioComponent GetAVFComponent() {
130 AudioComponent component = NULL;
131 pthread_mutex_lock(&gAVFComponentLock);
132
133 if (!gAVFComponent) {
134 gAVFComponent = AUBaseFactory<AVFKernelComponent>::Register(kAudioUnitType_Effect,
135 'Krnl',
136 'JAVA',
137 CFSTR("JavaFX Kernel Processor"),
138 0x00010000);
139 }
140 component = gAVFComponent;
141
142 pthread_mutex_unlock(&gAVFComponentLock);
143 return component;
144 }
145
146
147 AudioUnit NewKernelProcessorUnit(AVFKernelProcessor *kernel) {
148 OSStatus status = noErr;
149 AudioUnit unit = NULL;
150 AudioComponent ac = GetAVFComponent();
151
152 if (!ac) {
153 return NULL;
154 }
155
156 status = AudioComponentInstanceNew(ac, &unit);
157 if (noErr == status) {
158 status = AudioUnitSetProperty(unit,
159 kAVFProperty_KernelProcessor,
160 kAudioUnitScope_Global,
161 0,
162 &kernel,
163 sizeof(AVFKernelProcessor**));
164 }
165
166 if (noErr != status) {
167 if (unit) {
168 AudioComponentInstanceDispose(unit);
169 }
170 }
171 return unit;
172 }
|
1 /*
2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include "AVFKernelProcessor.h"
27
28 #include <pthread.h>
29
30 // Apple reserves 0-1024 for their own properties
31 #define kAVFProperty_KernelProcessor 2099
32
33 class AVFKernelComponent : AUEffectBase {
34 public:
35 AVFKernelComponent(AudioComponentInstance audioUnit, bool inProcessesInPlace = true)
36 : AUEffectBase(audioUnit, inProcessesInPlace),
37 mUsesKernel(false),
38 mProcessor(nullptr)
39 {}
40
41 virtual ~AVFKernelComponent() {
42 mProcessor = nullptr;
43 }
44
45 virtual AUKernelBase *NewKernel() {
46 if (mProcessor != nullptr) {
47 AUKernelBase *kernel = mProcessor->NewKernel();
48 mUsesKernel = (kernel != NULL);
49 return kernel;
50 }
51 mUsesKernel = false;
52 return NULL;
53 }
54
55 virtual OSStatus ChangeStreamFormat(AudioUnitScope inScope,
56 AudioUnitElement inElement,
57 const CAStreamBasicDescription &inPrevFormat,
58 const CAStreamBasicDescription &inNewFormat) {
59 OSStatus status = this->AUEffectBase::ChangeStreamFormat(inScope,
60 inElement,
61 inPrevFormat,
62 inNewFormat);
63 if (mProcessor != nullptr && inScope == kAudioUnitScope_Input && inElement == 0) {
64 mProcessor->StreamFormatChanged(inNewFormat);
65 }
66 return status;
67 }
68
69 virtual OSStatus ProcessBufferLists(AudioUnitRenderActionFlags& ioActionFlags,
70 const AudioBufferList& inBuffer,
71 AudioBufferList& outBuffer,
72 UInt32 inFramesToProcess) {
73 // Call our base class if we have kernels
74 if (mUsesKernel) {
75 return this->AUEffectBase::ProcessBufferLists(ioActionFlags,
76 inBuffer,
77 outBuffer,
78 inFramesToProcess);
79 }
80 // Otherwise call ProcessBufferLists
81 if (mProcessor != nullptr) {
82 return mProcessor->ProcessBufferLists(ioActionFlags,
83 inBuffer,
84 outBuffer,
85 inFramesToProcess);
86 }
87 return noErr; // ??? just in case
88 }
89
90 virtual OSStatus SetProperty(AudioUnitPropertyID inID,
91 AudioUnitScope inScope,
92 AudioUnitElement inElement,
93 const void *inData,
94 UInt32 inDataSize) {
95 if (inID == kAVFProperty_KernelProcessor &&
96 inScope == kAudioUnitScope_Global &&
97 inElement == 0) {
98 if (inDataSize == sizeof(AVFKernelProcessor*)) {
99 AVFKernelProcessorPtr processor = *((AVFKernelProcessorPtr*)inData);
100 // this compares the raw pointers, not the shared_ptr itself
101 if (mProcessor != processor) {
102 if (mProcessor != nullptr) {
103 mProcessor->SetAudioUnit(NULL);
104 mProcessor = nullptr;
105 }
106
107 mProcessor = processor;
108 if (mProcessor != nullptr) {
109 mProcessor->SetAudioUnit(this);
110 const AudioStreamBasicDescription& format =
111 GetStreamFormat(kAudioUnitScope_Input, 0);
112 mProcessor->StreamFormatChanged(format);
113 }
114 }
115 return noErr;
116 }
117 return kAudioUnitErr_InvalidPropertyValue;
118 }
119 return this->AUEffectBase::SetProperty(inID, inScope, inElement, inData, inDataSize);
120 }
121 private:
122 bool mUsesKernel;
123 AVFKernelProcessorPtr mProcessor;
124 };
125
126 // Synchronize registration of the component
127 volatile AudioComponent gAVFComponent = NULL;
128 pthread_mutex_t gAVFComponentLock = PTHREAD_MUTEX_INITIALIZER;
129
130 static inline AudioComponent GetAVFComponent() {
131 AudioComponent component = NULL;
132 pthread_mutex_lock(&gAVFComponentLock);
133
134 if (!gAVFComponent) {
135 gAVFComponent = AUBaseFactory<AVFKernelComponent>::Register(kAudioUnitType_Effect,
136 'Krnl',
137 'JAVA',
138 CFSTR("JavaFX Kernel Processor"),
139 0x00010000);
140 }
141 component = gAVFComponent;
142
143 pthread_mutex_unlock(&gAVFComponentLock);
144 return component;
145 }
146
147
148 AudioUnit NewKernelProcessorUnit(AVFKernelProcessorPtr kernel) {
149 OSStatus status = noErr;
150 AudioUnit unit = NULL;
151 AudioComponent ac = GetAVFComponent();
152
153 if (!ac) {
154 return NULL;
155 }
156
157 status = AudioComponentInstanceNew(ac, &unit);
158 if (noErr == status) {
159 status = AudioUnitSetProperty(unit,
160 kAVFProperty_KernelProcessor,
161 kAudioUnitScope_Global,
162 0,
163 &kernel,
164 sizeof(AVFKernelProcessorPtr*));
165 }
166
167 if (noErr != status) {
168 if (unit) {
169 AudioComponentInstanceDispose(unit);
170 }
171 }
172 return unit;
173 }
|