def decode_position(self): """Get the current position of the decode head Returns: A tuple of (playlist_item, seconds). If the playlist is empty playlist_item will be None and seconds will be -1.0 """ pitem_obj_ptr = ffi.new('struct GroovePlaylistItem **') seconds = ffi.new('double *') lib.groove_encoder_position(self._obj, pitem_obj_ptr, seconds) return self._pitem(pitem_obj_ptr[0]), float(seconds[0])
def encode(cls, fp): """Compress and base64-encode a raw fingerprint""" # TODO: error handling efp_obj_ptr = ffi.new('char **') fp_obj = ffi.new('int32_t[]', fp) assert lib.groove_fingerprinter_encode(fp_obj, len(fp), efp_obj_ptr) == 0 # copy the result to python and free the c obj result = ffi.string(efp_obj_ptr[0]) lib.groove_fingerprinter_dealloc(efp_obj_ptr[0]) return result
def decode(cls, encoded_fp): """Uncompress and base64-decode a raw fingerprint""" efp_obj = ffi.new('char[]', encoded_fp) fp_obj_ptr = ffi.new('int32_t **') size_obj_ptr = ffi.new('int *') assert lib.groove_fingerprinter_decode(efp_obj, fp_obj_ptr, size_obj_ptr) == 0 # copy the result to python and free the c obj fp_obj = fp_obj_ptr[0] result = [int(fp_obj[n]) for n in range(size_obj_ptr[0])] lib.groove_fingerprinter_dealloc(fp_obj) return result
def position(self): """Get the current position of the printer head Returns: A tuple of (playlist_item, seconds). If the playlist is empty playlist_item will be None and seconds will be -1.0 """ pitem_obj_ptr = ffi.new('struct GroovePlaylistItem **') seconds = ffi.new('double *') lib.groove_loudness_detector_position(self._obj, pitem_obj_ptr, seconds) if pitem_obj_ptr[0] == ffi.NULL: pitem = None else: pitem = self.playlist._pitem(pitem_obj_ptr[0]) return pitem, float(seconds[0])
def position(self): """Get the current position of the printer head Returns: A tuple of (playlist_item, seconds). If the playlist is empty playlist_item will be None and seconds will be -1.0 """ pitem_obj_ptr = ffi.new('struct GroovePlaylistItem **') seconds = ffi.new('double *') lib.groove_fingerprinter_position(self._obj, pitem_obj_ptr, seconds) if pitem_obj_ptr[0] == ffi.NULL: pitem = None else: pitem = self.playlist._pitem(pitem_obj_ptr[0]) return pitem, float(seconds[0])
def setter(self, value): if value is None: setattr(self._obj, attr, ffi.NULL) setattr(self, uattr, None) else: # Keep a reference to this in python # or else it will be freed when gc happens value = ffi.new('char[]', value.encode(encoding)) setattr(self._obj, attr, value) setattr(self, uattr, value)
def event_get(self, block=False): """Get player event""" event_obj = ffi.new('union GroovePlayerEvent *') result = lib.groove_player_event_get(self._obj, event_obj, block) assert result >= 0 if result == 0: return None return PlayerEvent.__values__[event_obj.type]
def __iter__(self): info_obj = ffi.new('struct GrooveFingerprinterInfo *'); while True: status = lib.groove_fingerprinter_info_get(self._obj, info_obj, True) assert status >= 0 if status != 1 or info_obj.item == ffi.NULL: break fp_obj = info_obj.fingerprint fp_size_obj = info_obj.fingerprint_size if self.base64_encode: efp_obj_ptr = ffi.new('char **') assert lib.groove_fingerprinter_encode(fp_obj, fp_size_obj, efp_obj_ptr) == 0 fp = ffi.string(efp_obj_ptr[0]) lib.groove_fingerprinter_dealloc(efp_obj_ptr[0]) else: fp = [int(fp_obj[n]) for n in range(fp_size_obj)] duration = float(info_obj.duration) pitem = self.playlist._pitem(info_obj.item) lib.groove_fingerprinter_free_info(info_obj) yield FingerprinterInfo(fp, duration, pitem)
def test_from_obj(self): obj = ffi.new(g.AudioFormat._ffitype, { 'sample_rate': 1, 'channel_layout': g.ChannelLayout.layout_stereo, 'sample_fmt': g.SampleFormat.s32, }) fmt, fmt_created = g.AudioFormat._from_obj(obj) fmt2, fmt2_created = g.AudioFormat._from_obj(obj) assert fmt.sample_rate == 1 assert fmt.channel_layout is g.ChannelLayout.layout_stereo assert fmt.sample_format is g.SampleFormat.s32 assert fmt is fmt2 assert fmt_created == True assert fmt2_created == False
def test_from_obj(self): obj = ffi.new( g.AudioFormat._ffitype, { 'sample_rate': 1, 'channel_layout': g.ChannelLayout.layout_stereo, 'sample_fmt': g.SampleFormat.s32, }) fmt, fmt_created = g.AudioFormat._from_obj(obj) fmt2, fmt2_created = g.AudioFormat._from_obj(obj) assert fmt.sample_rate == 1 assert fmt.channel_layout is g.ChannelLayout.layout_stereo assert fmt.sample_format is g.SampleFormat.s32 assert fmt is fmt2 assert fmt_created == True assert fmt2_created == False
def __iter__(self): info_obj = ffi.new('struct GrooveLoudnessDetectorInfo *'); pitem = True while pitem: status = lib.groove_loudness_detector_info_get(self._obj, info_obj, True) assert status >= 0 if status != 1: break loudness = float(info_obj.loudness) peak = float(info_obj.peak) duration = float(info_obj.duration) if info_obj.item == ffi.NULL: pitem = None else: pitem = self.playlist._pitem(info_obj.item) yield LoudnessDetectorInfo(loudness, peak, duration, pitem)
def __iter__(self): info_obj = ffi.new('struct GrooveLoudnessDetectorInfo *') pitem = True while pitem: status = lib.groove_loudness_detector_info_get( self._obj, info_obj, True) assert status >= 0 if status != 1: break loudness = float(info_obj.loudness) peak = float(info_obj.peak) duration = float(info_obj.duration) if info_obj.item == ffi.NULL: pitem = None else: pitem = self.playlist._pitem(info_obj.item) yield LoudnessDetectorInfo(loudness, peak, duration, pitem)
def get_buffer(self, block=False): """Get the buffer on the sink If no buffer is ready, this raises `groove.Buffer.NotReady` If the end of the playlist is reached, this raises `groove.Buffer.End` If block is True and no buffer is ready, this may block indefinately """ # TODO: add timeout, might have to be done in libgroove to be safe buff_obj_ptr = ffi.new('struct GrooveBuffer **') value = lib.groove_sink_buffer_get(self._obj, buff_obj_ptr, block) assert value >= 0 if value == _constants.GROOVE_BUFFER_NO: raise Buffer.NotReady() elif value == _constants.GROOVE_BUFFER_END: raise Buffer.End() elif value == _constants.GROOVE_BUFFER_YES: buff = self.BufferClass._from_obj(buff_obj_ptr[0]) buff.sink = self return buff raise Exception('Unknown value %s from groove_sink_buffer_get' % value)
def get_buffer(self, block=False): """Get the buffer on the encoder If no buffer is ready, this raises `groove.Buffer.NotReady` If the end of the playlist is reached, this raises `groove.Buffer.End` If block is True and no buffer is ready, this may block indefinately """ # TODO: add timeout, might have to be done in libgroove to be safe buff_obj_ptr = ffi.new('struct GrooveBuffer **') value = lib.groove_encoder_buffer_get(self._obj, buff_obj_ptr, 1 if block else 0) assert value >= 0 if value == _constants.GROOVE_BUFFER_NO: raise Buffer.NotReady() elif value == _constants.GROOVE_BUFFER_END: raise Buffer.End() elif value == _constants.GROOVE_BUFFER_YES: buff, _ = self.BufferClass._from_obj(buff_obj_ptr[0]) buff.encoder = self return buff raise Exception('Unknown value %s from groove_encoder_buffer_get' % value)
def get_tags(self, flags=0): """Get the tags for an encoder Args: flags (int) Bitmask of tag flags Returns: A dictionary of `name: value` pairs. Both `name` and `value` will be type `bytes`. """ # Have to make a GrooveTag** so cffi doesn't try to sizeof GrooveTag gtag_ptr = ffi.new('struct GrooveTag **') gtag = gtag_ptr[0] tags = OrderedDict() while True: gtag = lib.groove_encoder_metadata_get(self._obj, b'', gtag, flags) if gtag == ffi.NULL: break key = ffi.string(lib.groove_tag_key(gtag)) value = ffi.string(lib.groove_tag_value(gtag)) tags[key] = value return tags
def __init__(self): self._obj = ffi.new(self._ffitype)