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.
Objcblock restype define question.
-
c_void_p(addressof(inBuffer))
or
cast(pointer(inBuffer),c_void_p)
or possibly just
addressof(inBuffer)
, but I am not sure about the last one...alternatively, what type does python think inBuffer is? Is it a custom Structure, or a c_void_p, etc? If it is a structure, you could set restype=POINTER(your_custom_struct), and then return pointer(inBuffer).
-
@JonB said:
-
ctypes.addressof(inBuffer) TypeError: invalid type
ctypes.cast(pointer(inBuffer),c_void_p) TypeError: type must have storage info -
maybe the restype = c_void_p is wrong, because c_void_p is int/long or None,but the <AVAudioBuffer> * Nullable it's a buffer. not int/long.
-
-
You will need to post actual code that got you this far. Where did you get inBuffer.
print(type(inBuffer))
-
@JonB
<class 'objc_util.ObjCInstance'> -
Can you post a gist of your code... it would help to be able to help, otherwise I am just throwing around guesses.
inBufferPtr=c_void_p(inBuffer.ptr) ... restype=POINTER(c_void_p) ... return pointer(inBufferPtr)
-
@JonB Test Code it's here.
# -*- coding: utf-8 -*- from objc_util import * import ctypes,time,os,struct,array,console # AVAudio Define AVAudioEngine=ObjCClass('AVAudioEngine') AVAudioSession=ObjCClass('AVAudioSession') AVAudioUnit=ObjCClass('AVAudioUnit') AVAudioPlayerNode=ObjCClass('AVAudioPlayerNode') AVAudioFile=ObjCClass('AVAudioFile') AVAudioPCMBuffer=ObjCClass('AVAudioPCMBuffer') AVAudioUnitEffect=ObjCClass('AVAudioUnitEffect') AVAudioFormat=ObjCClass('AVAudioFormat') AVAudioCompressedBuffer=ObjCClass('AVAudioCompressedBuffer') AVAudioConverter=ObjCClass('AVAudioConverter') # AVAudioFormat: 0-other,1-PCM float32,2 PCM float64,3-PCM int16,4-PCM int32 informat = AVAudioFormat.alloc().initWithCommonFormat_sampleRate_channels_interleaved_(3,44100,2,False) outformat = AVAudioFormat.alloc().initWithSettings_(ns({'AVSampleRateKey':44100,'AVNumberOfChannelsKey':2,'AVFormatIDKey':struct.unpack('I', b' caa')[0]})) # ,'mFramesPerPacket':1024})) inBuffer = AVAudioPCMBuffer.alloc().initWithPCMFormat_frameCapacity_(informat,4096) converter = AVAudioConverter.alloc().initFromFormat_toFormat_(informat,outformat) outBuffer = AVAudioCompressedBuffer.alloc().initWithFormat_packetCapacity_maximumPacketSize_(outformat, 8,converter.maximumOutputPacketSize()) gcnt = 0 # typedef AVAudioBuffer * _Nullable (^AVAudioConverterInputBlock)(AVAudioPacketCount inNumberOfPackets, AVAudioConverterInputStatus *outStatus); def conv_block(self,inNumberOfPackets,buffstat): global gcnt # buffstat: 0-have data 1-no data 2-endOfStream 3-error print '@1',inNumberOfPackets,buffstat.contents.value gcnt += 1 if gcnt == 1: buffstat.contents.value = 0 print '@2',inNumberOfPackets,buffstat.contents.value print '!!! InBuff:',inBuffer,type(inBuffer),ctypes.cast(inBuffer,ctypes.c_void_p) #,ctypes.addressof(inBuffer) return None #pointer(c_void_p(inBuffer.ptr)) else: buffstat.contents.value = 2 return None #convblock=ObjCBlock(conv_block,restype=POINTER(c_void_p),argtypes=[c_void_p,c_int32,POINTER(c_long)]) convblock=ObjCBlock(conv_block,restype=c_void_p,argtypes=[c_void_p,c_int32,POINTER(c_long)]) error=ctypes.c_void_p(0) status = converter.convertToBuffer_error_withInputFromBlock_(outBuffer,error,convblock) print '>>Ret1:',status print '>>out1:',outBuffer if error: print '>>Err:',ObjCInstance(error) status = converter.convertToBuffer_error_withInputFromBlock_(outBuffer,None,convblock) print '>>Ret2:',status print '>>out2:',outBuffer
-
if using restype=POINTER(c_void_p)
Error:
PythonistaKit.framework/pylib/site-packages/objc_util.py", line 955, in init
block.invoke = InvokeFuncType(func)
TypeError: invalid result type for callback function -
@JonB I Try Using this, it's ok.
return inBuffer.ptr
convblock=ObjCBlock(conv_block,restype=c_void_p,argtypes=[c_void_p,c_int32,POINTER(c_long)])
-
@JonB other question.
the outBuffer.data() is a UnsafeMutableRawPointer,
print outBuffer.data() # >>> c_void_p(4635022848) # I need get data,so using oData = ObjCInstance(outBuffer.data()) # but Pythonista crash.
How Can get the data?
-
here is an example i found
http://stackoverflow.com/questions/13723384/audioconverter-number-of-packets-is-wrongdata looks undocumented, you need to go through the audioBufferList, imthink.
For dealing with pointers to buffers, there are a few ways, depening on how you want to fill the data. For the buffer you have to create, probably c_buffer(lengthInBytes) creates the buffer, then use addressof or pointer to get a pointer to the buffer.
For the one you need to read, cast to a (c_charlengthBytes), or use (c_charlengthBytes).from_address, then use regular slicing to access the contents as bytes.
-
@JonB Thanks.
tbuf = (ctypes.c_int16*1024).from_address(outBuffer.data().value) # Not error,and using tbuf[1] can get data. # It's right ??