Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
How to call objc function
-
@wolf71 said:
CACurrentMediaTime
Thanks.
just using:
from ctypes import *
c = cdl.LoadLibrary(None)
c.CACurrentMediaTime() -
@wolf71 you need to set the return tupe, and argtypes, though in this case argtypes=[].
c = cdll.LoadLibrary(None)
c.CACurrentMediaTime
c.CACurrentMediaTime.restype=c_double
print(c.CACurrentMediaTime()) -
@JonB Thank you.
-
@JonB How to get the ios default values?
etc: get NSDefaultRunLoopMode values -
@wolf71 since most of these are defined as constants or macros, it's difficult to get their value at runtime. The easiest solution would be to pass the "raw" value of the constant in your code, instead of the constant itself. You can create a new playground in Xcode and just log the constant.
If it's an enum, you usually can just look at the documentation and count which case you need (they're represented by integers starting at 0) -
@lukaskollmer Thanks.
@JonB How can defind a struct for objc?
etc: AudioStreamBasicDescription (it's objc structure).
and using this to init. init(mSampleRate:mFormatID:mFormatFlags:mBytesPerPacket:mFramesPerPacket:mBytesPerFrame:mChannelsPerFrame:mBitsPerChannel:mReserved:) -
@wolf71 said:
etc: get NSDefaultRunLoopMode values
Many constants can be found using in_dll for the appropriate ctypes type. For instance, NSDefaultRunLoopMode is declared as a NSString, therefore the appropriate ctypes type is a c_void_p. Calling ObjCInstance then gives you the object.
NSDefaultRunLoopMode=ObjCInstance(c_void_p.in_dll(c,'NSDefaultRunLoopMode').value)
It really seems like you are doing things the hard way... not sure what you are trying to actually do, but if you just want to create a thread, using
threading
... -
Since this is declared as a STRUCT and not an object, you need to use a ctypes struct.
import ctypes class AudioStreamBasicDescription(ctypes.Structure): _fields_=[('mSampleRate',ctypes.c_double), ('mFormatID',ctypes.c_uint32), ('mFormatFlags',ctypes.c_uint32), ('mBytesPerPacket',ctypes.c_uint32), ('mBytesPerFrame',ctypes.c_uint32), ('mBitsPerChannel',ctypes.c_uint32), ('mReserved',ctypes.c_uint32)]
You initialize by passing positional or keyword arguments, or just init and set attributes.
bd=AudioStreamBasicDescription() #all zeros bd.mSampleRate=11025 or bd=AudioStreamBasicDescription(11025, ........) or bd=AudioStreamBasicDescription(mSampleRate=11025, ........)
are all basically the same.
Obviously, you need to figure out the right flags, etc to use. You may need to us a variation ofimport struct struct.unpack('L', b'lpcm')
for the formatId, see the apple docs for the right 4 char code.
-
@JonB Thanks.
This code crash.
** initWithStreamDescription:(const AudioStreamBasicDescription *)asbd
** The AVAudioFormat need this type: <objc_util.LP_AudioStreamBasicDescription_Structure object at 0x10d02c148>
but the AudioStreamBasicDescription is <main.AudioStreamBasicDescription object at 0x110512048>class AudioStreamBasicDescription(ctypes.Structure): _fields_=[('mSampleRate',ctypes.c_double),('mFormatID',ctypes.c_uint32),('mFormatFlags',ctypes.c_uint32),('mBytesPerPacket',ctypes.c_uint32),('mFramesPerPacket',ctypes.c_uint32),('mBytesPerFrame',ctypes.c_uint32),('mChannelsPerFrame',ctypes.c_uint32),('mBitsPerChannel',ctypes.c_uint32),('mReserved',ctypes.c_uint32)] outformat = AVAudioFormat.alloc().initWithStreamDescription_(AudioStreamBasicDescription(44100,1,0,0,0,0,2,0,0))
-
This is a case where you need to override argtypes to point to your structure definition, since the auto definition will not match yours.
Also, I am pretty sure your formatID is invalid. I think you need the four byte code described in the apple docs.
Actually... for what its worth, consider using one of the initWithCommonFormat or initWithStandardFormat methods, which eliminate the need to create your own stream description.
-
@JonB ok,Thanks.
other question: how to define a NSUinteger * var?
# getBuffer:(uint8_t * _Nullable *)buffer length:(NSUInteger *)len aabuf = c_char_p() aalen = c_ulong() inStream.getBuffer_length_(aabuf,aalen)
Error: type 'exceptions.TypeError'>: expected LP_c_ulong instance instead of c_long
-
Using:
inStream.getBuffer_length_(aabuf,pointer(aalen)) ???
or inStream.getBuffer_length_(aabuf,byref(aalen)) -
@wolf71 In this case you need to pass both arguments using
byref
. The first argument (buffer
) is a pointer-to-pointer-to-char, andaabuf
is a pointer-to-char, so you need to usebyref
to make it a pointer-to-pointer. Same with the next one -len
needs to be a pointer-to-long, andaalen
is a long, so you need to put it throughbyref
to make it a pointer.