示例#1
0
    def start(self):
        """Start processing audio, and start calling the callback."""

        status = _au.AudioUnitInitialize(self.ptr[0])
        if status:
            raise RuntimeError(_cac.error_number_to_string(status))
        status = _au.AudioOutputUnitStart(self.ptr[0])
        if status:
            raise RuntimeError(_cac.error_number_to_string(status))
示例#2
0
    def close(self):
        """Stop processing audio, and stop calling the callback."""

        status = _au.AudioOutputUnitStop(self.ptr[0])
        if status:
            raise RuntimeError(_cac.error_number_to_string(status))
        status = _au.AudioComponentInstanceDispose(self.ptr[0])
        if status:
            raise RuntimeError(_cac.error_number_to_string(status))
        del self.ptr
示例#3
0
    def __init__(self, iotype, device, samplerate, channels, blocksize):
        self._iotype = iotype

        desc = _ffi.new(
            "AudioComponentDescription*",
            dict(componentType=_cac.kAudioUnitType_Output,
                 componentSubType=_cac.kAudioUnitSubType_HALOutput,
                 componentFlags=0,
                 componentFlagsMask=0,
                 componentManufacturer=_cac.kAudioUnitManufacturer_Apple))

        audiocomponent = _au.AudioComponentFindNext(_ffi.NULL, desc)
        if not audiocomponent:
            raise Runtime("could not find audio component")
        self.ptr = _ffi.new("AudioComponentInstance*")
        status = _au.AudioComponentInstanceNew(audiocomponent, self.ptr)
        if status:
            raise RuntimeError(_cac.error_number_to_string(status))

        if iotype == 'input':
            self.enableinput = True
            self.enableoutput = False
            self._au_scope = _cac.kAudioUnitScope_Output
            self._au_element = 1
        elif iotype == 'output':
            self.enableinput = False
            self.enableoutput = True
            self._au_scope = _cac.kAudioUnitScope_Input
            self._au_element = 0

        self.device = device

        blocksize = blocksize or self.blocksize

        # Input AudioUnits can't use non-native sample rates.
        # Therefore, if a non-native sample rate is requested, use a
        # resampled block size and resample later, manually:
        if iotype == 'input':
            self.resample = self.samplerate / samplerate
            # blocksize = math.ceil(blocksize*self.resample)
            # self.samplerate stays at its default value
        else:
            self.resample = 1
            self.samplerate = samplerate

        # there are two maximum block sizes for some reason:
        maxblocksize = min(self.blocksizerange[1], self.maxblocksize)
        if self.blocksizerange[0] <= blocksize <= maxblocksize:
            self.blocksize = blocksize
        else:
            raise TypeError("blocksize must be between {} and {}".format(
                self.blocksizerange[0], maxblocksize))

        if isinstance(channels, collections.Iterable):
            self.channels = len(channels)
            self.channelmap = channels
        elif isinstance(channels, int):
            self.channels = channels
        else:
            raise TypeError('channels must be iterable or integer')
示例#4
0
 def _get_property(self, property, scope, element, type, num_elements=1):
     data = _ffi.new(type)
     datasize = _ffi.new("UInt32*", _ffi.sizeof(_ffi.typeof(data).item.cname)*num_elements)
     status = _au.AudioUnitGetProperty(self.ptr[0],
                                       property, scope, element,
                                       data, datasize)
     if status != 0:
         raise RuntimeError(_cac.error_number_to_string(status))
     return data
示例#5
0
 def _set_property(self, property, scope, element, data):
     if '[]' in _ffi.typeof(data).cname:
         num_values = len(data)
     else:
         num_values = 1
     status = _au.AudioUnitSetProperty(self.ptr[0],
                                       property, scope, element,
                                       data, _ffi.sizeof(_ffi.typeof(data).item.cname)*num_values)
     if status != 0:
         raise RuntimeError(_cac.error_number_to_string(status))
示例#6
0
 def _get_property(self, property, scope, element, type):
     datasize = _ffi.new("UInt32*")
     status = _au.AudioUnitGetPropertyInfo(self.ptr[0], property, scope,
                                           element, datasize, _ffi.NULL)
     num_values = datasize[0] // _ffi.sizeof(type)
     data = _ffi.new(type + '[{}]'.format(num_values))
     status = _au.AudioUnitGetProperty(self.ptr[0], property, scope,
                                       element, data, datasize)
     if status != 0:
         raise RuntimeError(_cac.error_number_to_string(status))
     if num_values == 1:
         return data[0]
     else:
         return data
示例#7
0
 def _set_property(self, property, scope, element, data, num_elements=1):
     status = _au.AudioUnitSetProperty(
         self.ptr[0], property, scope, element, data,
         _ffi.sizeof(_ffi.typeof(data).item.cname) * num_elements)
     if status != 0:
         raise RuntimeError(_cac.error_number_to_string(status))