python/demos/demo_reading_speed.py: avoid unused variable
[aubio.git] / python / demos / demo_reading_speed.py
1 #! /usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5
6 Compare the speed of several methods for reading and loading a sound file.
7
8 Optionally, this file can make use of the following packages:
9
10     - audioread     https://github.com/beetbox/audioread
11     - scipy         https://scipy.org
12     - librosa       https://github.com/bmcfee/librosa
13     - pydub         https://github.com/jiaaro/pydub
14
15 Uncomment the function names below and send us your speed results!
16
17 """
18
19
20 test_functions = [
21             "read_file_aubio",
22             "load_file_aubio",
23             #"load_file_scipy",
24             #"load_file_scipy_mmap",
25             #"read_file_audioread",
26             #"load_file_librosa",
27             #"read_file_pydub",
28             #"load_file_pydub",
29             ]
30
31
32 import numpy as np
33
34 def read_file_audioread(filename):
35     import audioread
36     # taken from librosa.util.utils
37     def convert_buffer_to_float(buf, n_bytes = 2, dtype = np.float32):
38         # Invert the scale of the data
39         scale = 1./float(1 << ((8 * n_bytes) - 1))
40         # Construct the format string
41         fmt = '<i{:d}'.format(n_bytes)
42         # Rescale and format the data buffer
43         out = scale * np.frombuffer(buf, fmt).astype(dtype)
44         return out
45
46     with audioread.audio_open(filename) as f:
47         total_frames = 0
48         for buf in f:
49             samples = convert_buffer_to_float(buf)
50             samples = samples.reshape(f.channels, -1)
51             total_frames += samples.shape[1]
52         return total_frames, f.samplerate
53
54 def load_file_librosa(filename):
55     import librosa
56     y, sr = librosa.load(filename, sr = None)
57     #print y.mean(), y.shape
58     return len(y), sr
59
60 def load_file_scipy(filename):
61     import scipy.io.wavfile
62     sr, y = scipy.io.wavfile.read(filename)
63     y = y.astype('float32') / 32767
64     #print y.mean(), y.shape
65     return len(y), sr
66
67 def load_file_scipy_mmap(filename):
68     import scipy.io.wavfile
69     sr, y = scipy.io.wavfile.read(filename, mmap = True)
70     #print y.mean(), y.shape
71     return len(y), sr
72
73 def read_file_pydub(filename):
74     from pydub import AudioSegment
75     song = AudioSegment.from_file(filename)
76     song.get_array_of_samples()
77     return song.frame_count(), song.frame_rate
78
79 def load_file_pydub(filename):
80     from pydub import AudioSegment
81     song = AudioSegment.from_file(filename)
82     y = np.asarray(song.get_array_of_samples(), dtype = 'float32')
83     y = y.reshape(song.channels, -1) / 32767.
84     return song.frame_count(), song.frame_rate
85
86 def read_file_aubio(filename):
87     import aubio
88     f = aubio.source(filename, hop_size = 1024)
89     total_frames = 0
90     while True:
91         _, read = f()
92         total_frames += read
93         if read < f.hop_size: break
94     return total_frames, f.samplerate
95
96 def load_file_aubio(filename):
97     import aubio
98     f = aubio.source(filename, hop_size = 1024)
99     y = np.zeros(f.duration, dtype = aubio.float_type)
100     total_frames = 0
101     while True:
102         samples, read = f()
103         y[total_frames:total_frames + read] = samples[:read]
104         total_frames += read
105         if read < f.hop_size: break
106     assert len(y) == total_frames
107     #print y.mean(), y.shape
108     return total_frames, f.samplerate
109
110 def test_speed(function, filename):
111     times = []
112     for _ in range(10):
113         start = time.time()
114         try:
115             total_frames, samplerate = function(filename)
116         except ImportError as e:
117             print ("error: failed importing {:s}".format(e))
118             return
119         elapsed = time.time() - start
120         #print ("{:5f} ".format(elapsed)),
121         times.append(elapsed)
122
123     #print
124     times = np.array(times)
125     duration_min = int(total_frames/float(samplerate) // 60)
126     str_format = '{:25s} took {:5f} seconds avg (±{:5f}) to run on a ~ {:d} minutes long file'
127     print (str_format.format(function.__name__, times.mean(), times.std(), duration_min ))
128
129 if __name__ == '__main__':
130     import sys, time
131     if len(sys.argv) < 2:
132         print ("not enough arguments")
133         sys.exit(1)
134     filename = sys.argv[1]
135
136     for f in test_functions:
137         # get actual function from globals
138         test_function = globals()[f]
139         test_speed(test_function, filename)