pyobjc-framework-MediaToolbox 12.2.2__tar.gz → 13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Lib/MediaToolbox/_metadata.py +12 -3
  2. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Lib/pyobjc_framework_MediaToolbox.egg-info/PKG-INFO +5 -5
  3. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Lib/pyobjc_framework_MediaToolbox.egg-info/SOURCES.txt +3 -3
  4. pyobjc_framework_mediatoolbox-13.0/Lib/pyobjc_framework_MediaToolbox.egg-info/pyobjc-build-info.txt +3 -0
  5. pyobjc_framework_mediatoolbox-13.0/Lib/pyobjc_framework_MediaToolbox.egg-info/requires.txt +2 -0
  6. pyobjc_framework_mediatoolbox-13.0/Modules/_MediaToolbox.m +517 -0
  7. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Modules/pyobjc-api.h +18 -4
  8. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Modules/pyobjc-compat.h +0 -18
  9. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/PKG-INFO +5 -5
  10. pyobjc_framework_mediatoolbox-13.0/PyObjCTest/test_mtaudioprocessingtap.py +629 -0
  11. pyobjc_framework_mediatoolbox-13.0/PyObjCTest/testtrack.m4a +0 -0
  12. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/metadata/MediaToolbox.fwinfo +10 -16
  13. pyobjc_framework_mediatoolbox-12.2.2/metadata/raw/arm64-26.5.fwinfo → pyobjc_framework_mediatoolbox-13.0/metadata/raw/arm64-27.fwinfo +35 -4
  14. pyobjc_framework_mediatoolbox-12.2.2/metadata/raw/x86_64-26.5.fwinfo → pyobjc_framework_mediatoolbox-13.0/metadata/raw/x86_64-27.fwinfo +35 -4
  15. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/pyobjc_setup.py +7 -7
  16. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/setup.py +1 -1
  17. pyobjc_framework_mediatoolbox-12.2.2/Lib/pyobjc_framework_MediaToolbox.egg-info/pyobjc-build-info.txt +0 -3
  18. pyobjc_framework_mediatoolbox-12.2.2/Lib/pyobjc_framework_MediaToolbox.egg-info/requires.txt +0 -2
  19. pyobjc_framework_mediatoolbox-12.2.2/Modules/_MediaToolbox.m +0 -438
  20. pyobjc_framework_mediatoolbox-12.2.2/PyObjCTest/test_mtaudioprocessingtap.py +0 -34
  21. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Examples/ProcessingTap/summary.txt +0 -0
  22. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Examples/ProcessingTap/tap.py +0 -0
  23. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Lib/MediaToolbox/__init__.py +0 -0
  24. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Lib/pyobjc_framework_MediaToolbox.egg-info/dependency_links.txt +0 -0
  25. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Lib/pyobjc_framework_MediaToolbox.egg-info/not-zip-safe +0 -0
  26. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/Lib/pyobjc_framework_MediaToolbox.egg-info/top_level.txt +0 -0
  27. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/License.txt +0 -0
  28. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/MANIFEST.in +0 -0
  29. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/PyObjCTest/__init__.py +0 -0
  30. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/PyObjCTest/test_mediatoolbox.py +0 -0
  31. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/PyObjCTest/test_mtformatnames.py +0 -0
  32. /pyobjc_framework_mediatoolbox-12.2.2/PyObjCTest/test_mtprofessionalvideoWorkflow.py → /pyobjc_framework_mediatoolbox-13.0/PyObjCTest/test_mtprofessionalvideoworkflow.py +0 -0
  33. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/metadata/metadata.ini +0 -0
  34. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/pyproject.toml +0 -0
  35. {pyobjc_framework_mediatoolbox-12.2.2 → pyobjc_framework_mediatoolbox-13.0}/setup.cfg +0 -0
@@ -1,7 +1,5 @@
1
1
  # This file is generated by objective.metadata
2
2
  #
3
- # Last update: Sun May 24 11:52:36 2026
4
- #
5
3
  # flake8: noqa
6
4
 
7
5
  import objc, sys
@@ -47,8 +45,19 @@ functions = {
47
45
  }
48
46
  },
49
47
  ),
50
- "MTAudioProcessingTapGetTypeID": (b"Q",),
48
+ "MTAudioProcessingTapGetStorage": (b"^v^{opaqueMTAudioProcessingTap=}",),
49
+ "MTAudioProcessingTapCreateWithPreferredFormat": (
50
+ b"i^{__CFAllocator=}@I^{opaqueCMFormatDescription=}^^{opaqueMTAudioProcessingTap=}",
51
+ "",
52
+ {"arguments": {4: {"already_cfretained": True, "type_modifier": "o"}}},
53
+ ),
54
+ "MTAudioProcessingTapCreate": (
55
+ b"i^{__CFAllocator=}@I^^{opaqueMTAudioProcessingTap=}",
56
+ "",
57
+ {"arguments": {3: {"already_cfretained": True, "type_modifier": "o"}}},
58
+ ),
51
59
  "MTRegisterProfessionalVideoWorkflowFormatReaders": (b"v",),
60
+ "MTAudioProcessingTapGetTypeID": (b"Q",),
52
61
  "MTCopyLocalizedNameForMediaType": (
53
62
  b"^{__CFString=}I",
54
63
  "",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyobjc-framework-MediaToolbox
3
- Version: 12.2.2
3
+ Version: 13.0
4
4
  Summary: Wrappers for the framework MediaToolbox on macOS
5
5
  Home-page: https://github.com/ronaldoussoren/pyobjc
6
6
  Author: Ronald Oussoren
@@ -17,21 +17,21 @@ Classifier: Operating System :: MacOS :: MacOS X
17
17
  Classifier: Programming Language :: Python
18
18
  Classifier: Programming Language :: Python :: 3
19
19
  Classifier: Programming Language :: Python :: 3 :: Only
20
- Classifier: Programming Language :: Python :: 3.10
21
20
  Classifier: Programming Language :: Python :: 3.11
22
21
  Classifier: Programming Language :: Python :: 3.12
23
22
  Classifier: Programming Language :: Python :: 3.13
24
23
  Classifier: Programming Language :: Python :: 3.14
25
24
  Classifier: Programming Language :: Python :: 3.15
25
+ Classifier: Programming Language :: Python :: 3.16
26
26
  Classifier: Programming Language :: Python :: Implementation :: CPython
27
27
  Classifier: Programming Language :: Python :: Free Threading :: 3 - Stable
28
28
  Classifier: Programming Language :: Objective C
29
29
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
30
30
  Classifier: Topic :: Software Development :: User Interfaces
31
- Requires-Python: >=3.10
31
+ Requires-Python: >=3.11
32
32
  Description-Content-Type: text/x-rst; charset=UTF-8
33
- Requires-Dist: pyobjc-core>=12.2.2
34
- Requires-Dist: pyobjc-framework-Cocoa>=12.2.2
33
+ Requires-Dist: pyobjc-core>=13.0
34
+ Requires-Dist: pyobjc-framework-Cocoa>=13.0
35
35
  Dynamic: author
36
36
  Dynamic: author-email
37
37
  Dynamic: classifier
@@ -21,9 +21,9 @@ PyObjCTest/__init__.py
21
21
  PyObjCTest/test_mediatoolbox.py
22
22
  PyObjCTest/test_mtaudioprocessingtap.py
23
23
  PyObjCTest/test_mtformatnames.py
24
- PyObjCTest/test_mtprofessionalvideoWorkflow.py
25
24
  PyObjCTest/test_mtprofessionalvideoworkflow.py
25
+ PyObjCTest/testtrack.m4a
26
26
  metadata/MediaToolbox.fwinfo
27
27
  metadata/metadata.ini
28
- metadata/raw/arm64-26.5.fwinfo
29
- metadata/raw/x86_64-26.5.fwinfo
28
+ metadata/raw/arm64-27.fwinfo
29
+ metadata/raw/x86_64-27.fwinfo
@@ -0,0 +1,3 @@
1
+ macOS 27.2 (26B123)
2
+ Apple clang version 21.0.0 (clang-2100.4.1.1)
3
+ SDK: macOS 27.2
@@ -0,0 +1,2 @@
1
+ pyobjc-core>=13.0
2
+ pyobjc-framework-Cocoa>=13.0
@@ -0,0 +1,517 @@
1
+ #define PY_SSIZE_T_CLEAN
2
+ #include "Python.h"
3
+ #include "pyobjc-api.h"
4
+
5
+ #ifdef USE_STATIC_ANALYZER
6
+ #include "../../pyobjc-core/Modules/objc/python-api-used.h"
7
+ #endif
8
+
9
+ #import <MediaToolbox/MediaToolbox.h>
10
+
11
+ NS_ASSUME_NONNULL_BEGIN
12
+
13
+ enum {
14
+ INFO_OFFSET,
15
+ INIT_OFFSET,
16
+ FINALIZE_OFFSET,
17
+ PREPARE_OFFSET,
18
+ UNPREPARE_OFFSET,
19
+ PROCESS_OFFSET,
20
+
21
+ OFFSET_COUNT
22
+ };
23
+
24
+ static void
25
+ init_callback(MTAudioProcessingTapRef tap, void* clientInfo, void** tapStorageOut)
26
+ {
27
+ PyObject* cb_info = (PyObject*)clientInfo;
28
+ PyObject* cb;
29
+ *tapStorageOut = clientInfo;
30
+ Py_INCREF(clientInfo);
31
+
32
+ cb = PyTuple_GET_ITEM(cb_info, INIT_OFFSET);
33
+
34
+ PyGILState_STATE state = PyGILState_Ensure();
35
+
36
+ if (cb != Py_None) {
37
+ PyObject* py_tap = PyObjC_ObjCToPython(@encode(MTAudioProcessingTapRef), &tap);
38
+ if (tap == NULL) // LCOV_BR_EXCL_LINE
39
+ goto error; // LCOV_EXCL_LINE
40
+ PyObject* rv = PyObject_CallFunction(
41
+ cb,
42
+ "NO"
43
+ "O",
44
+ py_tap, PyTuple_GET_ITEM(cb_info, INFO_OFFSET), Py_None);
45
+ if (rv == NULL)
46
+ goto error;
47
+ Py_DECREF(PyTuple_GET_ITEM(clientInfo, INFO_OFFSET));
48
+ PyTuple_SET_ITEM(clientInfo, INFO_OFFSET, rv);
49
+ }
50
+
51
+ PyGILState_Release(state);
52
+ return;
53
+
54
+ error:
55
+ fputs("Ignoring exception in MTAudioProcessing callback\n", stderr);
56
+ PyErr_Print();
57
+ Py_DECREF(PyTuple_GET_ITEM(clientInfo, INFO_OFFSET));
58
+ PyTuple_SET_ITEM(clientInfo, INFO_OFFSET, Py_None);
59
+ Py_INCREF(Py_None);
60
+ PyGILState_Release(state);
61
+ }
62
+
63
+ static void
64
+ finalize_callback(MTAudioProcessingTapRef tap)
65
+ {
66
+ PyObject* cb_info = (PyObject*)MTAudioProcessingTapGetStorage(tap);
67
+
68
+ PyObject* cb = PyTuple_GET_ITEM(cb_info, FINALIZE_OFFSET);
69
+
70
+ PyGILState_STATE state = PyGILState_Ensure();
71
+
72
+ if (cb != Py_None) {
73
+ PyObject* pytap = PyObjC_ObjCToPython(@encode(MTAudioProcessingTapRef), &tap);
74
+ if (pytap == NULL) // LCOV_BR_EXCL_LINE
75
+ goto error; // LCOV_EXCL_LINE
76
+ PyObject* rv = PyObject_CallFunctionObjArgs(cb, pytap, NULL);
77
+ Py_CLEAR(pytap);
78
+ if (rv == NULL)
79
+ goto error;
80
+
81
+ Py_CLEAR(rv);
82
+ }
83
+
84
+ /* The finalize callback is the last time any callback will be called,
85
+ * therefore clean up the python state information.
86
+ */
87
+ Py_XDECREF(cb_info);
88
+ PyGILState_Release(state);
89
+ return;
90
+
91
+ error:
92
+ fputs("Ignoring exception in MTAudioProcessing callback\n", stderr);
93
+ PyErr_Print();
94
+
95
+ Py_XDECREF(cb_info);
96
+ PyGILState_Release(state);
97
+ }
98
+
99
+ static void
100
+ prepare_callback(MTAudioProcessingTapRef tap, CMItemCount maxFrames,
101
+ const AudioStreamBasicDescription* processingFormat)
102
+ {
103
+ PyObject* cb_info = (PyObject*)MTAudioProcessingTapGetStorage(tap);
104
+
105
+ PyObject* cb = PyTuple_GET_ITEM(cb_info, PREPARE_OFFSET);
106
+
107
+ PyGILState_STATE state = PyGILState_Ensure();
108
+
109
+ if (cb != Py_None) {
110
+ PyObject* rv = PyObject_CallFunction(
111
+ cb, "NNN", PyObjC_ObjCToPython(@encode(MTAudioProcessingTapRef), &tap),
112
+ PyObjC_ObjCToPython(@encode(CMItemCount), &maxFrames),
113
+ PyObjC_ObjCToPython(@encode(AudioStreamBasicDescription),
114
+ (void*)processingFormat));
115
+ if (rv == NULL)
116
+ goto error;
117
+ Py_XDECREF(rv);
118
+ }
119
+
120
+ PyGILState_Release(state);
121
+ return;
122
+
123
+ error:
124
+ fputs("Ignoring exception in MTAudioProcessing callback\n", stderr);
125
+ PyErr_Print();
126
+ PyGILState_Release(state);
127
+ }
128
+
129
+ static void
130
+ unprepare_callback(MTAudioProcessingTapRef tap)
131
+ {
132
+ PyObject* cb_info = (PyObject*)MTAudioProcessingTapGetStorage(tap);
133
+
134
+ PyObject* cb = PyTuple_GET_ITEM(cb_info, UNPREPARE_OFFSET);
135
+
136
+ PyGILState_STATE state = PyGILState_Ensure();
137
+
138
+ if (cb != Py_None) {
139
+ PyObject* rv = PyObject_CallFunction(
140
+ cb, "N", PyObjC_ObjCToPython(@encode(MTAudioProcessingTapRef), &tap));
141
+ if (rv == NULL) {
142
+ goto error;
143
+ }
144
+ Py_XDECREF(rv);
145
+ }
146
+
147
+ PyGILState_Release(state);
148
+ return;
149
+
150
+ error:
151
+ fputs("Ignoring exception in MTAudioProcessing callback\n", stderr);
152
+ PyErr_Print();
153
+ PyGILState_Release(state);
154
+ }
155
+
156
+ static void
157
+ process_callback(MTAudioProcessingTapRef tap, CMItemCount numberFrames,
158
+ MTAudioProcessingTapFlags flags, AudioBufferList* bufferListInOut,
159
+ CMItemCount* numberFramesOut, MTAudioProcessingTapFlags* flagsOut)
160
+ {
161
+ PyObject* cb_info = (PyObject*)MTAudioProcessingTapGetStorage(tap);
162
+
163
+ PyObject* cb = PyTuple_GET_ITEM(cb_info, PROCESS_OFFSET);
164
+
165
+ PyGILState_STATE state = PyGILState_Ensure();
166
+
167
+ if (cb != Py_None) {
168
+ PyObject* py_bufferListInOut;
169
+ PyObject* rv = PyObject_CallFunction(
170
+ cb, "NNNNOO", PyObjC_ObjCToPython(@encode(MTAudioProcessingTapRef), &tap),
171
+ PyObjC_ObjCToPython(@encode(CMItemCount), &numberFrames),
172
+ PyObjC_ObjCToPython(@encode(MTAudioProcessingTapFlags), &flags),
173
+ (py_bufferListInOut =
174
+ PyObjC_ObjCToPython(@encode(AudioBufferList*), &bufferListInOut)),
175
+ Py_None, Py_None);
176
+ if (rv == NULL)
177
+ goto error;
178
+
179
+ if (!PyTuple_Check(rv) || PyTuple_Size(rv) != 3) {
180
+ PyErr_SetString(PyExc_TypeError,
181
+ "MTAudioProcessing processing callback should return "
182
+ "(bufferListInOut, numFrames, flags)\n");
183
+ goto error;
184
+ }
185
+ if (PyTuple_GET_ITEM(rv, 0) != py_bufferListInOut) {
186
+ /* XXX: Is this correct? Can one replace the bufferList entirely? */
187
+ PyErr_SetString(PyExc_TypeError,
188
+ "MTAudioProcessing processing callback should return "
189
+ "(bufferListInOut, numFrames, flags)\n");
190
+ goto error;
191
+ }
192
+ (void)PyObjC_PythonToObjC(@encode(CMItemCount), PyTuple_GET_ITEM(rv, 1),
193
+ (void*)numberFramesOut);
194
+ (void)PyObjC_PythonToObjC(@encode(MTAudioProcessingTapFlags),
195
+ PyTuple_GET_ITEM(rv, 2), (void*)flagsOut);
196
+ Py_CLEAR(rv);
197
+ if (PyErr_Occurred()) {
198
+ goto error;
199
+ }
200
+ }
201
+
202
+ PyGILState_Release(state);
203
+ return;
204
+ error:
205
+ fputs("Ignoring exception in MTAudioProcessing callback\n", stderr);
206
+ PyErr_Print();
207
+ PyGILState_Release(state);
208
+ }
209
+
210
+ static MTAudioProcessingTapCallbacks callback_template = {
211
+ .version = kMTAudioProcessingTapCallbacksVersion_0,
212
+ .clientInfo = NULL,
213
+ .init = init_callback,
214
+ .finalize = finalize_callback,
215
+ .prepare = prepare_callback,
216
+ .unprepare = unprepare_callback,
217
+ .process = process_callback};
218
+
219
+ static PyObject* _Nullable m_MTAudioProcessingTapCreate(
220
+ PyObject* meth, PyObject* _Nonnull const* _Nonnull args, size_t nargs)
221
+ {
222
+ unsigned int flags;
223
+
224
+ CFAllocatorRef allocator;
225
+ MTAudioProcessingTapCallbacks callbacks = callback_template;
226
+ MTAudioProcessingTapRef tap;
227
+ PyObject* info;
228
+ int i;
229
+ OSStatus rv;
230
+
231
+ if (PyObjC_CheckArgCount(meth, 4, 4, nargs) == -1) {
232
+ return NULL;
233
+ }
234
+
235
+ if (PyObjC_PythonToObjC(@encode(CFAllocatorRef), args[0], &allocator) == -1) {
236
+ return NULL;
237
+ }
238
+
239
+ if (!PyTuple_Check(args[1]) || PyTuple_Size(args[1]) != 7) {
240
+ PyErr_SetString(PyExc_ValueError, "callbacks should be tuple of 7 items");
241
+ return NULL;
242
+ }
243
+
244
+ if (PyObjC_PythonToObjC(@encode(unsigned int), args[2], &flags) == -1) {
245
+ return NULL;
246
+ }
247
+
248
+ if (args[3] != Py_None) {
249
+ PyErr_SetString(PyExc_ValueError, "'tapOut' should be None");
250
+ return NULL;
251
+ }
252
+
253
+ if (!PyLong_Check(PyTuple_GET_ITEM(args[1], 0))
254
+ || PyLong_AsLong(PyTuple_GET_ITEM(args[1], 0))
255
+ != kMTAudioProcessingTapCallbacksVersion_0) {
256
+ PyErr_SetString(PyExc_ValueError,
257
+ "callbacks[0] must be kMTAudioProcessingTapCallbacksVersion_0");
258
+ return NULL;
259
+ }
260
+ /* Note: callbacks[1] can be an arbitrary object */
261
+ for (i = 2; i < 7; i++) {
262
+ /* Most callbacks can be either None or a callable */
263
+ if (i != 6 && PyTuple_GET_ITEM(args[1], i) == Py_None)
264
+ continue;
265
+
266
+ if (!PyCallable_Check(PyTuple_GET_ITEM(args[1], i))) {
267
+ PyErr_Format(PyExc_ValueError, "callbacks[%d] should be callable", i);
268
+ return NULL;
269
+ }
270
+ }
271
+
272
+ info = PyTuple_Pack(OFFSET_COUNT, PyTuple_GET_ITEM(args[1], 1),
273
+ PyTuple_GET_ITEM(args[1], 2), PyTuple_GET_ITEM(args[1], 3),
274
+ PyTuple_GET_ITEM(args[1], 4), PyTuple_GET_ITEM(args[1], 5),
275
+ PyTuple_GET_ITEM(args[1], 6));
276
+ if (info == NULL) { // LCOV_BR_EXCL_LINE
277
+ return NULL; // LCOV_EXCL_LINE
278
+ }
279
+
280
+ callbacks.clientInfo = info;
281
+
282
+ Py_BEGIN_ALLOW_THREADS
283
+ @try {
284
+ rv = MTAudioProcessingTapCreate(allocator, &callbacks, flags, &tap);
285
+
286
+ } @catch (NSException* localException) { // LCOV_EXCL_LINE
287
+ PyObjCErr_FromObjC(localException); // LCOV_EXCL_LINE
288
+ rv = -1; // LCOV_EXCL_LINE
289
+ }
290
+ Py_END_ALLOW_THREADS
291
+
292
+ if (rv == -1 && PyErr_Occurred()) { // LCOV_BR_EXCL_LINE
293
+ Py_DECREF(info); // LCOV_EXCL_LINE
294
+ return NULL; // LCOV_EXCL_LINE
295
+ }
296
+
297
+ if (rv != 0) {
298
+ Py_DECREF(info);
299
+ }
300
+
301
+ PyObject* py_tapOut;
302
+ if (rv == 0) {
303
+ py_tapOut = PyObjC_ObjCToPython(@encode(MTAudioProcessingTapRef), &tap);
304
+ CFRelease(tap);
305
+ } else {
306
+ py_tapOut = Py_None;
307
+ Py_INCREF(Py_None);
308
+ }
309
+
310
+ return Py_BuildValue("lN", (long)rv, py_tapOut);
311
+ }
312
+
313
+ #if PyObjC_BUILD_RELEASE >= 2700
314
+ #pragma clang diagnostic ignored "-Wunknown-pragmas"
315
+ #pragma clang diagnostic ignored "-Wunguarded-availability-new"
316
+
317
+ static PyObject* _Nullable m_MTAudioProcessingTapCreateWithPreferredFormat(
318
+ PyObject* meth, PyObject* _Nonnull const* _Nonnull args, size_t nargs)
319
+ {
320
+ unsigned int flags;
321
+
322
+ CFAllocatorRef allocator;
323
+ MTAudioProcessingTapCallbacks callbacks = callback_template;
324
+ CMAudioFormatDescriptionRef preferredFormat;
325
+ MTAudioProcessingTapRef tap;
326
+ PyObject* info;
327
+ int i;
328
+ OSStatus rv;
329
+
330
+ if (PyObjC_CheckArgCount(meth, 5, 5, nargs) == -1) {
331
+ return NULL;
332
+ }
333
+
334
+ if (PyObjC_PythonToObjC(@encode(CFAllocatorRef), args[0], &allocator) == -1) {
335
+ return NULL;
336
+ }
337
+
338
+ if (!PyTuple_Check(args[1]) || PyTuple_Size(args[1]) != 7) {
339
+ PyErr_SetString(PyExc_ValueError, "callbacks should be tuple of 7 items");
340
+ return NULL;
341
+ }
342
+
343
+ if (PyObjC_PythonToObjC(@encode(unsigned int), args[2], &flags) == -1) {
344
+ return NULL;
345
+ }
346
+
347
+ if (PyObjC_PythonToObjC(@encode(CMAudioFormatDescriptionRef), args[3],
348
+ &preferredFormat)
349
+ == -1) {
350
+ return NULL;
351
+ }
352
+
353
+ if (args[4] != Py_None) {
354
+ PyErr_SetString(PyExc_ValueError, "'tapOut' should be None");
355
+ return NULL;
356
+ }
357
+ if (!PyLong_Check(PyTuple_GET_ITEM(args[1], 0))
358
+ || PyLong_AsLong(PyTuple_GET_ITEM(args[1], 0))
359
+ != kMTAudioProcessingTapCallbacksVersion_0) {
360
+ PyErr_SetString(PyExc_ValueError,
361
+ "callbacks[0] must be kMTAudioProcessingTapCallbacksVersion_0");
362
+ return NULL;
363
+ }
364
+ /* callbacks[1] can be an arbitrary value */
365
+ for (i = 2; i < 7; i++) {
366
+ /* Most callbacks can be either None or a callable */
367
+ if (i != 6 && PyTuple_GET_ITEM(args[1], i) == Py_None)
368
+ continue;
369
+
370
+ if (!PyCallable_Check(PyTuple_GET_ITEM(args[1], i))) {
371
+ PyErr_Format(PyExc_ValueError, "callbacks[%d] should be callable", i);
372
+ return NULL;
373
+ }
374
+ }
375
+
376
+ info = PyTuple_Pack(OFFSET_COUNT, PyTuple_GET_ITEM(args[1], 1),
377
+ PyTuple_GET_ITEM(args[1], 2), PyTuple_GET_ITEM(args[1], 3),
378
+ PyTuple_GET_ITEM(args[1], 4), PyTuple_GET_ITEM(args[1], 5),
379
+ PyTuple_GET_ITEM(args[1], 6));
380
+
381
+ if (info == NULL) { // LCOV_BR_EXCL_LINE
382
+ return NULL; // LCOV_EXCL_LINE
383
+ }
384
+
385
+ callbacks.clientInfo = info;
386
+
387
+ Py_BEGIN_ALLOW_THREADS
388
+ @try {
389
+ rv = MTAudioProcessingTapCreateWithPreferredFormat(
390
+ allocator, &callbacks, flags, preferredFormat, &tap);
391
+
392
+ } @catch (NSException* localException) {
393
+ PyObjCErr_FromObjC(localException);
394
+ rv = -1;
395
+ }
396
+ Py_END_ALLOW_THREADS
397
+ Py_DECREF(info);
398
+
399
+ if (rv == -1 && PyErr_Occurred()) {
400
+ return NULL;
401
+ }
402
+
403
+ if (rv != 0) {
404
+ Py_DECREF(info);
405
+ }
406
+
407
+ PyObject* py_tapOut;
408
+ if (rv == 0) {
409
+ py_tapOut = PyObjC_ObjCToPython(@encode(MTAudioProcessingTapRef), &tap);
410
+ CFRelease(tap);
411
+ } else {
412
+ py_tapOut = Py_None;
413
+ Py_INCREF(Py_None);
414
+ }
415
+
416
+ return Py_BuildValue("lN", (long)rv, py_tapOut);
417
+ }
418
+
419
+ #pragma clang diagnostic pop
420
+ #endif
421
+
422
+ static PyObject* _Nullable m_MTAudioProcessingTapGetStorage(
423
+ PyObject* meth, PyObject* _Nonnull const* _Nonnull args, size_t nargs)
424
+ {
425
+ MTAudioProcessingTapRef tap;
426
+ PyObject* cb_info;
427
+
428
+ if (PyObjC_CheckArgCount(meth, 1, 1, nargs) == -1) {
429
+ return NULL;
430
+ }
431
+
432
+ if (PyObjC_PythonToObjC(@encode(MTAudioProcessingTapRef), args[0], &tap) == -1) {
433
+ return NULL;
434
+ }
435
+
436
+ cb_info = (PyObject*)MTAudioProcessingTapGetStorage(tap);
437
+ Py_INCREF(PyTuple_GET_ITEM(cb_info, INFO_OFFSET));
438
+ return PyTuple_GET_ITEM(cb_info, INFO_OFFSET);
439
+ }
440
+
441
+ static PyMethodDef mod_methods[] = {
442
+
443
+ {NULL} /* Sentinel */
444
+ };
445
+
446
+ static int
447
+ mod_exec_module(PyObject* m)
448
+ {
449
+ if (PyObjC_ImportAPI(m) < 0) { // LCOV_BR_EXCL_LINE
450
+ return -1; // LCOV_EXCL_LINE
451
+ }
452
+
453
+ if (PyObjCRegister_FunctionCaller(MTAudioProcessingTapCreate,
454
+ m_MTAudioProcessingTapCreate)
455
+ == -1) { // LCOV_BR_EXCL_LINE
456
+ return -1; // LCOV_EXCL_LINE
457
+ }
458
+ if (PyObjCRegister_FunctionCaller(MTAudioProcessingTapGetStorage,
459
+ m_MTAudioProcessingTapGetStorage)
460
+ == -1) { // LCOV_BR_EXCL_LINE
461
+ return -1; // LCOV_EXCL_LINE
462
+ }
463
+ #if PyObjC_BUILD_RELEASE >= 2700
464
+ if (__builtin_available(macOS 27.0, *)) {
465
+ if (PyObjCRegister_FunctionCaller(MTAudioProcessingTapCreateWithPreferredFormat,
466
+ m_MTAudioProcessingTapCreateWithPreferredFormat)
467
+ == -1) { // LCOV_BR_EXCL_LINE
468
+ return -1; // LCOV_EXCL_LINE
469
+ }
470
+ }
471
+ #endif
472
+ return 0;
473
+ }
474
+
475
+ static struct PyModuleDef_Slot mod_slots[] = {
476
+ {.slot = Py_mod_exec, .value = (void*)mod_exec_module},
477
+ #if PY_VERSION_HEX >= 0x030c0000
478
+ {
479
+ /* This extension does not use the CPython API other than initializing
480
+ * the module, hence is safe with subinterpreters and per-interpreter
481
+ * GILs
482
+ */
483
+ .slot = Py_mod_multiple_interpreters,
484
+ .value = Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED,
485
+ },
486
+ #endif
487
+ #if PY_VERSION_HEX >= 0x030d0000
488
+ {
489
+ /* The code in this extension should be safe to use without the GIL */
490
+ .slot = Py_mod_gil,
491
+ .value = Py_MOD_GIL_NOT_USED,
492
+ },
493
+ #endif
494
+ {/* Sentinel */
495
+ .slot = 0,
496
+ .value = 0}};
497
+
498
+ static struct PyModuleDef mod_module = {
499
+ .m_base = PyModuleDef_HEAD_INIT,
500
+ .m_name = "_MediaToolbox",
501
+ .m_doc = NULL,
502
+ .m_size = 0,
503
+ .m_methods = mod_methods,
504
+ .m_slots = mod_slots,
505
+ .m_traverse = NULL,
506
+ .m_clear = NULL,
507
+ .m_free = NULL,
508
+ };
509
+
510
+ PyObject* _Nullable PyInit__MediaToolbox(void);
511
+
512
+ PyObject* _Nullable __attribute__((__visibility__("default")))
513
+ PyInit__MediaToolbox(void)
514
+ {
515
+ return PyModuleDef_Init(&mod_module);
516
+ }
517
+ NS_ASSUME_NONNULL_END
@@ -60,6 +60,11 @@ typedef int(RegisterMethodMappingFunctionType)(
60
60
  PyObject* _Nonnull const* _Nonnull, size_t),
61
61
  IMP _Nullable (*_Nonnull)(PyObject* _Nonnull, PyObject* _Nonnull));
62
62
 
63
+ #ifndef PyObjC_FUNCTION_CALL_H
64
+ typedef PyObject* _Nullable (*PyObjC_FunctionCallFunc)(
65
+ PyObject* meth, PyObject* _Nonnull const* _Nonnull args, size_t nargs);
66
+ #endif
67
+
63
68
  struct pyobjc_api {
64
69
  int api_version; /* API version */
65
70
  size_t struct_len; /* Length of this struct */
@@ -117,6 +122,9 @@ struct pyobjc_api {
117
122
 
118
123
  PyObject* _Nullable (*_Nonnull createopaquepointertype)(const char*, const char*,
119
124
  const char*);
125
+ int (*_Nonnull register_functioncaller)(void*, PyObjC_FunctionCallFunc);
126
+ PyObject* _Nullable (*_Nonnull create_registered_struct)(
127
+ const char*, Py_ssize_t, const char* _Nonnull* _Nullable, Py_ssize_t*);
120
128
  };
121
129
 
122
130
  #ifndef PYOBJC_BUILD
@@ -159,6 +167,8 @@ static struct pyobjc_api* PyObjC_API;
159
167
  #define PyObjC_CheckArgCount (PyObjC_API->checkargcount)
160
168
  #define PyObjC_CheckNoKwnames (PyObjC_API->checknokwnames)
161
169
  #define PyObjCCreateOpaquePointerType (PyObjC_API->createopaquepointertype)
170
+ #define PyObjCRegister_FunctionCaller (PyObjC_API->register_functioncaller)
171
+ #define PyObjC_CreateRegisteredStruct (PyObjC_API->create_registered_struct)
162
172
 
163
173
  typedef void (*PyObjC_Function_Pointer)(void);
164
174
  typedef struct PyObjC_function_map {
@@ -178,21 +188,25 @@ static inline int
178
188
  PyObjC_ImportAPI(PyObject* calling_module)
179
189
  {
180
190
  PyObjC_API = (struct pyobjc_api*)PyCapsule_Import("objc." PYOBJC_API_NAME, 0);
181
- if (PyObjC_API == NULL) {
182
- return -1;
191
+ if (PyObjC_API == NULL) { // LCOV_BR_EXCL_LINE
192
+ return -1; // LCOV_EXCL_LINE
183
193
  }
184
- if (PyObjC_API->api_version != PYOBJC_API_VERSION) {
194
+ if (PyObjC_API->api_version != PYOBJC_API_VERSION) { // LCOV_BR_EXCL_LINE
195
+ // LCOV_EXCL_START
185
196
  PyErr_Format(PyExc_RuntimeError,
186
197
  "Wrong version of PyObjC C API (got %d, expected %d)",
187
198
  (int)PyObjC_API->api_version, (int)PYOBJC_API_VERSION);
188
199
  return -1;
200
+ // LCOV_EXCL_STOP
189
201
  }
190
202
 
191
- if (PyObjC_API->struct_len < PyObjC_EXPECTED_STRUCT_SIZE) {
203
+ if (PyObjC_API->struct_len < PyObjC_EXPECTED_STRUCT_SIZE) { // LCOV_EXCL_LINE
204
+ // LCOV_EXCL_START
192
205
  PyErr_Format(PyExc_RuntimeError,
193
206
  "Wrong struct-size of PyObjC C API (got %d, expected %d)",
194
207
  (int)PyObjC_API->struct_len, (int)sizeof(struct pyobjc_api));
195
208
  return -1;
209
+ // LCOV_EXCL_STOP
196
210
  }
197
211
 
198
212
  /* Current pyobjc implementation doesn't allow deregistering
@@ -167,24 +167,6 @@ _PyObjCTuple_GetItem(PyObject* tuple, Py_ssize_t idx)
167
167
  PyGILState_Release(_GILState); \
168
168
  } while (0)
169
169
 
170
- #if PY_VERSION_HEX < 0x030a0000
171
-
172
- static inline PyObject*
173
- Py_NewRef(PyObject* o)
174
- {
175
- Py_INCREF(o);
176
- return o;
177
- }
178
-
179
- static inline PyObject*
180
- Py_XNewRef(PyObject* o)
181
- {
182
- Py_XINCREF(o);
183
- return o;
184
- }
185
-
186
- #endif /* PY_VERSION_HEX < 0x030a0000 */
187
-
188
170
  #if PY_VERSION_HEX < 0x030d0000
189
171
  #define Py_BEGIN_CRITICAL_SECTION(value) \
190
172
  { \