source: interfaces/python/aubioinput.py @ 1c190d5

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 1c190d5 was 1c190d5, checked in by Paul Brossier <piem@piem.org>, 15 years ago

aubioinput.py: added first draft of generic gst input

  • Property mode set to 100644
File size: 4.0 KB
Line 
1#! /usr/bin/python
2
3import pygst
4pygst.require('0.10')
5import gst
6import gobject
7gobject.threads_init ()
8
9def gst_buffer_to_numpy_array(buffer, chan):
10    import numpy
11    samples = numpy.frombuffer(buffer.data, dtype=numpy.float32) 
12    samples.resize([len(samples)/chan, chan])
13    return samples.T
14
15class AubioSink(gst.BaseSink):
16    _caps = gst.caps_from_string('audio/x-raw-float, \
17                    rate=[ 1, 2147483647 ], \
18                    channels=[ 1, 2147483647 ], \
19                    endianness={ 1234, 4321 }, \
20                    width=32')
21
22    __gsttemplates__ = ( 
23            gst.PadTemplate ("sink",
24                gst.PAD_SINK,
25                gst.PAD_ALWAYS,
26                _caps),
27            )
28
29    def __init__(self, name, process):
30        self.__gobject_init__()
31        self.set_name(name)
32        self.process = process
33        self.adapter = gst.Adapter()
34        self.set_property('sync', False)
35        self.pos = 0
36
37    def set_property(self, name, value): 
38        if name == 'hopsize':
39            # blocksize is in byte, convert from hopsize
40            from struct import calcsize
41            self.set_property('blocksize', value * calcsize('f'))
42        else:
43            super(gst.BaseSink, self).set_property(name, value)
44
45    def do_render(self, buffer):
46        blocksize = self.get_property('blocksize')
47        caps = buffer.get_caps()
48        chan = caps[0]['channels']
49        self.adapter.push(buffer)
50        while self.adapter.available() >= blocksize:
51            block = self.adapter.take_buffer(blocksize)
52            v = gst_buffer_to_numpy_array(block, chan)
53            if self.process:
54                self.process(v, self.pos)
55            self.pos += 1   
56        return gst.FLOW_OK
57
58gobject.type_register(AubioSink)
59
60class aubioinput:
61    def __init__(self, location, process = None, hopsize = 512,
62            caps = None):
63        from os.path import isfile
64        if not isfile(location):
65            raise ValueError, "location should be a file"
66        src = gst.element_factory_make('filesrc')
67        src.set_property('location', location)
68        dec = gst.element_factory_make('decodebin')
69        dec.connect('new-decoded-pad', self.on_new_decoded_pad)
70        conv = gst.element_factory_make('audioconvert')
71        rsmpl = gst.element_factory_make('audioresample')
72        capsfilter = gst.element_factory_make('capsfilter')
73        if caps:
74            capsfilter.set_property('caps', gst.caps_from_string(caps))
75        sink = AubioSink("AubioSink", process = process)
76        sink.set_property('hopsize', hopsize) # * calcsize('f'))
77
78        self.pipeline = gst.Pipeline()
79
80        self.bus = self.pipeline.get_bus()
81        self.bus.add_signal_watch()
82        self.bus.connect('message::eos', self.on_eos)
83
84        self.apad = conv.get_pad('sink')
85
86        self.pipeline.add(src, dec, conv, rsmpl, capsfilter, sink)
87
88        src.link(dec)
89        gst.element_link_many(conv, rsmpl, capsfilter, sink)
90
91        self.mainloop = gobject.MainLoop()
92        self.pipeline.set_state(gst.STATE_PLAYING)
93        self.mainloop.run()
94
95    def on_new_decoded_pad(self, element, pad, last):
96        caps = pad.get_caps()
97        name = caps[0].get_name()
98        #print 'on_new_decoded_pad:', name
99        if name == 'audio/x-raw-float' or name == 'audio/x-raw-int':
100            if not self.apad.is_linked(): # Only link once
101                pad.link(self.apad)
102
103    def on_eos(self, bus, msg):
104        self.bus.remove_signal_watch()
105        self.pipeline.set_state(gst.STATE_PAUSED)
106        self.mainloop.quit()
107
108if __name__ == '__main__':
109    import sys
110    if len(sys.argv) < 2:
111        print "Usage: %s <filename>" % sys.argv[0]
112        sys.exit(1)
113    for filename in sys.argv[1:]:
114        peak = [0., 0.]
115        def process(buf, hop):
116            peak[0] = max( peak[0], abs(buf.max()) )
117            peak[1] = min( peak[1], abs(buf.min()) )
118        aubioinput(filename, process = process, hopsize = 512)
119        print "Finished reading %s, peak value is %f" % (filename, min(peak))
Note: See TracBrowser for help on using the repository browser.