├── Music_genre_classification.ipynb
├── README.md
├── audiofile_read.py
├── filelist_GTZAN_mp3_wclasses.txt
├── keras.json
├── requirements.txt
├── rp_extract.py
└── wavio.py
/README.md:
--------------------------------------------------------------------------------
1 | # Tutorial: Deep Learning on Music Information Retrieval
2 |
3 | (c) 2017 by Thomas Lidy, TU Wien - http://ifs.tuwien.ac.at/~lidy
4 |
5 | This is a set of tutorials showing how to use Deep learning algorithms for music analysis and retrieval problems. More specifically, we use Convolutional Neural Networks to classify (categorize) music into genres.
6 |
7 | It uses Python 2.7 as the programming language with the popular [Keras](https://keras.io/) and [Theano](http://deeplearning.net/software/theano/) Deep Learning libraries underneath.
8 |
9 | # Tutorials
10 |
11 | For the tutorials, we use iPython / Jupyter notebook, which allows to program and execute Python code interactively in the browser.
12 |
13 | ### Viewing Only
14 |
15 | If you do not want to install anything, you can simply view the tutorials' content in your browser, by clicking on
16 | the tutorial's filenames listed below in the GIT file listing (above, resp. on https://github.com/tuwien-musicir/DL_MIR_Tutorial ).
17 |
18 | The tutorial will open in your browser for viewing.
19 |
20 | ### Interactive Coding
21 |
22 | If you want to follow the Tutorials by actually executing the code on your computer, please [install first the pre-requisites](#installation-of-pre-requisites) as described below.
23 |
24 | After that, to run the tutorials go into the `DL_MIR_Tutorial` folder and start from the command line:
25 |
26 | `ipython notebook` or `jupyter notebook`
27 |
28 | Your web browser will open showing a list of files. Start the tutorials one after another by clicking on the following:
29 |
30 | Music_genre_classification.ipynb
31 | This tutorial shows how music is categorized into 1 of 10 music genres using the GTZAN music collection (see below).
32 | It includes audio and data preprocessing for Deep Learning and creating and training different architectures and parameters of a Convolutional Neural Network. It also includes techniques such as Batch Normalization, ReLU Activation and Dropout.
33 |
34 |
35 | # Installation of Pre-requisites
36 |
37 | ## Install Python 2.7
38 |
39 | Note: On most Mac and Linux systems Python is already pre-installed. Check with `python --version` on the command line whether you have Python 2.7.x installed.
40 |
41 | Otherwise install Python 2.7 from https://www.python.org/download/releases/2.7/
42 |
43 | ## Install Python libraries:
44 |
45 | ### Mac, Linux or Windows
46 |
47 | (on Windows leave out `sudo`)
48 |
49 | ```
50 | sudo pip install ipython
51 | ```
52 |
53 | Try if you can open
54 | ```
55 | ipython notebook
56 | ```
57 | on the command line. Otherwise try to install:
58 | ```
59 | sudo pip install jupyter
60 | ```
61 |
62 | Then download or clone the Tutorials from this GIT repository:
63 |
64 | ```
65 | git clone https://github.com/tuwien-musicir/DL_MIR_Tutorial.git
66 | ```
67 | or download https://github.com/tuwien-musicir/DL_MIR_Tutorial/archive/master.zip
68 | unzip it and rename the folder to `DL_MIR_Tutorial`.
69 |
70 | Install the remaining Python libraries needed:
71 |
72 | Either by:
73 |
74 | ```
75 | sudo pip install Keras==1.2.1 Theano==0.8.2 scikit-learn>=0.17 pandas librosa
76 | ```
77 |
78 | or, if you downloaded or cloned this repository, by:
79 |
80 | ```
81 | cd DL_MIR_Tutorial
82 | sudo pip install -r requirements.txt
83 | ```
84 |
85 | ### Install MP3 Decoder
86 |
87 | If you want to use audio formats other than .wav files (e.g. .mp3, .flac, .au, .mp4), you have to install FFMPEG on you computer:
88 |
89 | - Linux: install `ffmpeg`, via `sudo apt-get install ffmpeg`)
90 | - for Ubuntu 14.04: see http://fcorti.com/2014/04/22/ffmpeg-ubuntu-14-04-lts
91 | - Mac: download FFMPeg for Mac: http://ffmpegmac.net or if you use brew, execute: `brew install ffmpeg`
92 | - Windows: download FFMpeg.exe from https://github.com/tuwien-musicir/rp_extract/blob/master/bin/external/win/ffmpeg.exe
93 |
94 | Make sure that the exectuable is in a PATH found by the system.
95 |
96 | ## Configure Keras to use Theano
97 |
98 | Since we use Theano as the Deep Learning computation backend, but Keras is configured to use TensorFlow by default, we have to change this in the `keras.json` configuration file, which is in the `.keras` folder of the user's HOME directory.
99 |
100 | Copy the `keras.json` included in the `DL_MIR_Tutorial` to one of the following target directories (you can overwrite an existing file):
101 |
102 | * Windows: `C:\Users\\.keras\`
103 | * Mac: `/Users//.keras`
104 | * Linux: `/home//.keras`
105 |
106 | An alternantive is to change these 2 lines in your `keras.json` file to the following:
107 | ```
108 | {
109 | "image_dim_ordering": "th",
110 | "backend": "theano"
111 | }
112 | ```
113 |
114 | See https://keras.io/backend/ for details or http://ankivil.com/installing-keras-theano-and-dependencies-on-windows-10/ for a step by step guide.
115 |
116 | ### Optional for GPU computation
117 |
118 | If you want to train your neural networks on your GPU, also install the following (not needed for the tutorials):
119 |
120 | * [NVidia drivers](http://www.nvidia.com/Download/index.aspx?lang=en-us)
121 | * [CUDA](https://developer.nvidia.com/cuda-downloads)
122 | * [cuDNN](https://developer.nvidia.com/cudnn) (optional, for further speedup)
123 |
124 | To permanently configure Keras/Theano to use the GPU place a file `.theanorc` in your home directory with the following content:
125 |
126 | ```
127 | [global]
128 | device = gpu
129 | floatX = float32
130 | mode=FAST_RUN
131 | ```
132 |
133 | ### Check if installed correctly
134 |
135 | To check whether Python, Keras and Theano were installed correctly, do:
136 |
137 | `
138 | python test_keras.py
139 | `
140 |
141 | If everything is installed correctly, it should print `Using Theano backend.`
142 | If the GPU is configured correctly, it should also print `Using gpu device 0: GeForce GTX 980 Ti` or similar.
143 |
144 |
145 | # Source Credits
146 |
147 | ## Python libraries
148 |
149 | The following helper Python libraries are used in these tutorials:
150 |
151 | * `audiofile_read.py` and `rp_extract.py`: by Thomas Lidy and Alexander Schindler, taken from the [RP_extract](https://github.com/tuwien-musicir/rp_extract) git repository
152 | * `wavio.py`: by Warren Weckesser
153 |
154 | ## Data Sources
155 |
156 | The data sets we use in the tutorials are from the following sources:
157 |
158 | * GTZAN music genre data set:
159 | by George Tzanetakis
160 | 1000 audio files with 30 sec. each, across 10 music genres, 100 audio files each
161 |
162 | * GTZAN music speech data set: (currently not used)
163 | by George Tzanetakis
164 | Collected for the purposes of music/speech discrimination. 128 tracks, each 30 seconds long. Each class (music or speech) has 64 examples in 22050Hz Mono 16-bit WAV audio format.
165 |
166 | both data sets available from:
167 | http://marsyasweb.appspot.com/download/data_sets/
168 |
--------------------------------------------------------------------------------
/audiofile_read.py:
--------------------------------------------------------------------------------
1 | # 2015-04 by Thomas Lidy
2 |
3 | # MP3 READ: mini function to decode mp3 using external program
4 | # as there is no Python library for it, we need to use external tools (mpg123, lame, ffmpeg)
5 |
6 | import os # for calling external program for mp3 decoding
7 | import subprocess # for subprocess calls
8 | import tempfile
9 | import uuid
10 |
11 | # Reading WAV files
12 | # from scipy.io import wavfile
13 | # scipy.io.wavfile does not support 24 bit Wav files
14 | # therefore we switch to wavio by Warren Weckesser - https://github.com/WarrenWeckesser/wavio - BSD 3-Clause License
15 | import wavio
16 |
17 |
18 |
19 | class DecoderException(Exception):
20 |
21 | def __init__(self, message, command=[], orig_error=None):
22 |
23 | # Call the base class constructor with the parameters it needs
24 | super(DecoderException, self).__init__(message)
25 | self.command = command
26 | self.original_error = orig_error
27 |
28 |
29 |
30 | def get_audioformat_info(input_file, split_list = True):
31 | import magic # pip install python-magic
32 | from string import split
33 | info = magic.from_file(input_file)
34 | if split_list:
35 | info = split(info, ', ')
36 | return info
37 |
38 |
39 |
40 | # Normalize integer WAV data to float in range (-1,1)
41 | # Note that this works fine with Wav files read with Wavio
42 | # when using scipy.io.wavfile to read Wav files, use divisor = np.iinfo(wavedata.dtype).max + 1
43 | # but in this case it will not work with 24 bit files due to scipy scaling 24 bit up to 32bit
44 | def normalize_wav(wavedata,samplewidth):
45 |
46 | # samplewidth in byte (i.e.: 1 = 8bit, 2 = 16bit, 3 = 24bit, 4 = 32bit)
47 | divisor = 2**(8*samplewidth)/2
48 | wavedata = wavedata / float(divisor)
49 | return (wavedata)
50 |
51 |
52 |
53 | def wav_read(filename,normalize=True,verbose=True,auto_resample=True):
54 | '''read WAV files
55 |
56 | :param filename: input filename to read from
57 | :param normalize: normalize the read values (usually signed integers) to range (-1,1)
58 | :param verbose: output some information during reading
59 | :param auto_resample: auto-resampling: if sample rate is different than 11, 22 or 44 kHz it will resample to 44 khZ
60 | :return: tuple of 3 elements: samplereate (e.g. 44100), samplewith (e.g. 2 for 16 bit) and wavedata (simple array for mono, 2-dim. array for stereo)
61 | '''
62 |
63 | # check if file exists
64 | if not os.path.exists(filename):
65 | raise NameError("File does not exist: " + filename)
66 |
67 | samplerate, samplewidth, wavedata = wavio.readwav(filename)
68 |
69 | if auto_resample and samplerate != 11025 and samplerate != 22050 and samplerate != 44100:
70 | #print original file info
71 | if verbose:
72 | print samplerate, "Hz,", wavedata.shape[1], "channel(s),", wavedata.shape[0], "samples"
73 |
74 | to_samplerate = 22050 if samplerate < 22050 else 44100
75 | filename2 = resample(filename, to_samplerate, normalize=True, verbose=verbose)
76 | samplerate, samplewidth, wavedata = wavio.readwav(filename2)
77 | os.remove(filename2) # delete temp file
78 |
79 | if (normalize):
80 | wavedata = normalize_wav(wavedata,samplewidth)
81 |
82 | return (samplerate, samplewidth, wavedata)
83 |
84 |
85 | def get_temp_filename(suffix=None):
86 |
87 | temp_dir = tempfile.gettempdir()
88 | rand_filename = str(uuid.uuid4())
89 |
90 | if suffix != None:
91 | rand_filename = "%s%s" % (rand_filename, suffix)
92 |
93 | return os.path.join(temp_dir, rand_filename)
94 |
95 |
96 | def resample(filename, to_samplerate=44100, normalize=True, verbose=True):
97 |
98 | tempfile = get_temp_filename(suffix='.wav')
99 |
100 | try:
101 | cmd = ['ffmpeg','-v','1','-y','-i', filename, '-ar', str(to_samplerate), tempfile]
102 | if verbose:
103 | print "Resampling to", to_samplerate, "..."
104 | #print " ".join(cmd)
105 |
106 | return_code = subprocess.call(cmd) # subprocess.call takes a list of command + arguments
107 |
108 | if return_code != 0:
109 | raise DecoderException("Problem appeared during resampling.", command=cmd)
110 | #if verbose: print 'Resampled with:', " ".join(cmd)
111 |
112 | except OSError as e:
113 | if os.path.exists(tempfile):
114 | os.remove(tempfile)
115 |
116 | if e.errno == 2: # probably ffmpeg binary not found
117 | try:
118 | subprocess.call(cmd[0]) # check if we can just call the binary
119 | except OSError as e:
120 | raise DecoderException("Decoder not found. Please install " + cmd[0], command=cmd, orig_error=e)
121 |
122 | raise DecoderException("Unknown problem appeared during resampling.", command=cmd, orig_error=e)
123 |
124 | return tempfile
125 |
126 |
127 |
128 | def mp3_decode(in_filename, out_filename=None, verbose=True):
129 | ''' mp3_decode
130 |
131 | decoding of MP3 files
132 |
133 | now handled by decode function (for parameters see there)
134 | kept for code compatibility
135 | '''
136 | return decode(in_filename, out_filename, verbose)
137 |
138 |
139 | def decode(in_filename, out_filename=None, verbose=True, no_extension_check=False, force_mono=False, force_resampling=None):
140 | ''' calls external decoder to convert an MP3, FLAC, AIF(F) or M4A file to a WAV file
141 |
142 | One of the following decoder programs must be installed on the system:
143 |
144 | ffmpeg: for mp3, flac, aif(f), or m4a
145 | mpg123: for mp3
146 | lame: for mp3
147 |
148 | (consider adding their path using os.environ['PATH'] += os.pathsep + path )
149 |
150 | in_filename: input audio file name to process
151 | out_filename: output filename after conversion; if omitted, the input filename is used, replacing the extension by .wav
152 | verbose: print decoding command line information or not
153 | no_extension_check: does not check file format extension. means that *first* specified decoder is called on ANY files type
154 | force_mono: force mono output when decoding (works with FFMPEG only!)
155 | force_resampling: force a target sampling rate (provided in Hz) when decoding (works with FFMPEG only!)
156 | returns: decoder command used (without parameters)
157 | '''
158 |
159 | basename, ext = os.path.splitext(in_filename)
160 | ext = ext.lower()
161 |
162 | if out_filename == None:
163 | out_filename = basename + '.wav'
164 |
165 | # check a number of external MP3 decoder tools whether they are available on the system
166 |
167 | # for subprocess.call, we prepare the commands and the arguments as a list
168 | # cmd_list is a list of commands with their arguments, which will be iterated over to try to find each tool
169 | # cmd_types is a list of file types supported by each command/tool
170 |
171 | cmd1 = ['ffmpeg','-v','1','-y','-i', in_filename] # -v adjusts log level, -y option overwrites output file, because it has been created already by tempfile before when passed
172 | if force_resampling: cmd1.extend(['-ar',str(force_resampling)]) # add option to resample to targate Hz
173 | if force_mono: cmd1.extend(['-ac','1']) # add option to force to mono (1 output channel)
174 | cmd1.append(out_filename)
175 | cmd1_types = ['.mp3','.m4a','.aif','.aiff','.flac']
176 |
177 | cmd2 = ['mpg123','-q', '-w', out_filename, in_filename]
178 | cmd2_types = ['.mp3']
179 |
180 | cmd3 = ['lame','--quiet','--decode', in_filename, out_filename]
181 | cmd3_types = ['.mp3']
182 |
183 | cmd_list = [cmd1,cmd2,cmd3]
184 | cmd_types = [cmd1_types,cmd2_types,cmd3_types]
185 |
186 | success = False
187 |
188 | for cmd, types in zip(cmd_list,cmd_types):
189 |
190 | # we decode only if the current command supports the file type that we are having (except no_extension_check is True)
191 | if ext in types or no_extension_check:
192 | try:
193 | return_code = subprocess.call(cmd) # subprocess.call takes a list of command + arguments
194 |
195 | if return_code != 0:
196 | raise DecoderException("Problem appeared during executing decoder. Return_code: " + str(return_code), command=cmd)
197 | if verbose: print 'Decoded', ext, 'with:', " ".join(cmd)
198 | success = True
199 |
200 | except OSError as e:
201 | if e.errno != 2: # 2 = No such file or directory (i.e. decoder not found, which we want to catch at the end below)
202 | raise DecoderException("Problem appeared during decoding: " + str(e), command=cmd, orig_error=e)
203 |
204 | if success:
205 | break # no need to loop further
206 |
207 | if not success:
208 | commands = ", ".join( c[0] for c in cmd_list)
209 | raise OSError("No appropriate decoder found for" + ext + " file. Check if any of these programs is on your system path: " + commands + \
210 | ". Otherwise install one of these and/or add them to the path using os.environ['PATH'] += os.pathsep + path.")
211 |
212 | return cmd[0]
213 |
214 | def get_supported_audio_formats():
215 | # TODO: update this list here every time a new format is added; to avoid this, make a more elegant solution getting the list of formats from where the commands are defined above
216 | return ('.wav','.mp3','.m4a','.aif','.aiff','.flac')
217 |
218 |
219 | # testing decoding to memory instead of file: did NOT bring any speedup!
220 | # Also note: sample rate and number of channels not returned with this method. can be derived with
221 | # ffprobe -v quiet -show_streams -of json
222 | # which already converts plain text to json, but then the json needs to be parsed.
223 | def decode_to_memory(in_filename, verbose=True):
224 | cmd1 = ['ffmpeg','-v','1','-y','-i', in_filename, "-f", "f32le", "pipe:1"] # -v adjusts log level, -y option overwrites output file, because it has been created already by tempfile above
225 | # "pipe:1" sends output to std_out (probably Linux only)
226 | # original: call = [cmd, "-v", "quiet", "-i", infile, "-f", "f32le", "-ar", str(sample_rate), "-ac", "1", "pipe:1"]
227 | # for Windows: \\.\pipe\from_ffmpeg # http://stackoverflow.com/questions/32157774/ffmpeg-output-pipeing-to-named-windows-pipe
228 | cmd1_types = ('.mp3','.aif','.aiff','.m4a')
229 |
230 | ext = ''
231 | if verbose: print 'Decoding', ext, 'with:', " ".join(cmd1)
232 |
233 | import numpy as np
234 | decoded_wav = subprocess.check_output(cmd1)
235 | wavedata = np.frombuffer(decoded_wav, dtype=np.float32)
236 | return wavedata
237 |
238 |
239 | def mp3_read(filename,normalize=True,verbose=True):
240 | ''' mp3_read:
241 | call mp3_decode and read from wav file ,then delete wav file
242 | returns samplereate (e.g. 44100), samplewith (e.g. 2 for 16 bit) and wavedata (simple array for mono, 2-dim. array for stereo)
243 | '''
244 |
245 | try:
246 | tempfile = get_temp_filename(suffix='.wav')
247 | decode(filename,tempfile,verbose)
248 | samplerate, samplewidth, wavedata = wav_read(tempfile,normalize,verbose)
249 |
250 | finally: # delete temp file
251 |
252 | if os.path.exists(tempfile):
253 | os.remove(tempfile)
254 |
255 | return (samplerate, samplewidth, wavedata)
256 |
257 |
258 |
259 | def audiofile_read(filename,normalize=True,verbose=True,include_decoder=False,no_extension_check=False,force_resampling=None):
260 | ''' audiofile_read
261 |
262 | generic function capable of reading WAV, MP3 and AIF(F) files
263 |
264 | :param filename: file name path to audio file
265 | :param normalize: normalize to (-1,1) if True (default), or keep original values (16 bit, 24 bit or 32 bit)
266 | :param verbose: whether to print a message while decoding files or not
267 | :param include_decoder: includes a 4th return value: string which decoder has been used to decode the audio file
268 | :param no_extension_check: does not check file format via extension. means that decoder is called on ALL files.
269 | :param force_resampling: force a target sampling rate (provided in Hz) when decoding (works with FFMPEG only!)
270 | :return: a tuple with 3 or 4 entries: samplerate in Hz (e.g. 44100), samplewidth in bytes (e.g. 2 for 16 bit),
271 | wavedata (simple array for mono, 2-dim. array for stereo), and optionally a decoder string
272 |
273 | Example:
274 | >>> samplerate, samplewidth, wavedata = audiofile_read("music/BoxCat_Games_-_10_-_Epic_Song.mp3",verbose=False)
275 | >>> print samplerate, "Hz,", samplewidth*8, "bit,", wavedata.shape[1], "channels,", wavedata.shape[0], "samples"
276 | 44100 Hz, 16 bit, 2 channels, 2421504 samples
277 |
278 | '''
279 |
280 | # check if file exists or has 0 bytes
281 | if not os.path.exists(filename):
282 | raise NameError("File does not exist: " + filename)
283 | if os.path.getsize(filename) == 0:
284 | raise ValueError("File has 0 bytes: " + filename)
285 |
286 | basename, ext = os.path.splitext(filename)
287 | ext = ext.lower()
288 |
289 | if ext == '.wav' and not no_extension_check==True:
290 | samplerate, samplewidth, wavedata = wav_read(filename,normalize,verbose)
291 | decoder = 'wavio.py' # for log file
292 | else:
293 | try: # try to decode
294 | tempfile = get_temp_filename(suffix='.wav')
295 | decoder = decode(filename,tempfile,verbose,no_extension_check,force_resampling=force_resampling)
296 | samplerate, samplewidth, wavedata = wav_read(tempfile,normalize,verbose)
297 |
298 | finally: # delete temp file in any case
299 | if os.path.exists(tempfile):
300 | os.remove(tempfile)
301 |
302 | if include_decoder:
303 | return samplerate, samplewidth, wavedata, decoder
304 | else:
305 | return samplerate, samplewidth, wavedata
306 |
307 |
308 | # function to self test audiofile_read if working properly
309 | def self_test():
310 | import doctest
311 | #doctest.testmod()
312 | doctest.run_docstring_examples(audiofile_read, globals())
313 |
314 |
315 | # main routine: to test if decoding works properly
316 |
317 | if __name__ == '__main__':
318 |
319 | # to run self test:
320 | #self_test()
321 | #exit()
322 | # (no output means that everything went fine)
323 |
324 | import sys
325 |
326 | # if your MP3 decoder is not on the system PATH, add it like this:
327 | # path = '/path/to/ffmpeg/'
328 | # os.environ['PATH'] += os.pathsep + path
329 |
330 | # test audio file: "Epic Song" by "BoxCat Game" (included in repository)
331 | # Epic Song by BoxCat Games is licensed under a Creative Commons Attribution License.
332 | # http://freemusicarchive.org/music/BoxCat_Games/Nameless_the_Hackers_RPG_Soundtrack/BoxCat_Games_-_Nameless-_the_Hackers_RPG_Soundtrack_-_10_Epic_Song
333 | if len(sys.argv) > 1:
334 | file = sys.argv[1]
335 | else:
336 | file = "music/BoxCat_Games_-_10_-_Epic_Song.mp3"
337 |
338 | #print get_audioformat_info(file)
339 |
340 | # import time
341 | # start = time.time()
342 | samplerate, samplewidth, wavedata = audiofile_read(file)
343 | # print time.time() - start
344 | # print wavedata.shape
345 | #
346 | # start = time.time()
347 | # wavedata2 = decode_to_memory(file)
348 | # print time.time() - start
349 | # print wavedata2.shape
350 | #
351 | # print "EQUAL" if wavedata == wavedata2 else "NOT EQUAL"
352 |
353 | print "Successfully read audio file:"
354 | print samplerate, "Hz,", samplewidth*8, "bit,", wavedata.shape[1], "channels,", wavedata.shape[0], "samples"
355 |
--------------------------------------------------------------------------------
/filelist_GTZAN_mp3_wclasses.txt:
--------------------------------------------------------------------------------
1 | ./rock/rock.00053.mp3,rock
2 | ./rock/rock.00051.mp3,rock
3 | ./rock/rock.00076.mp3,rock
4 | ./rock/rock.00084.mp3,rock
5 | ./rock/rock.00052.mp3,rock
6 | ./rock/rock.00057.mp3,rock
7 | ./rock/rock.00028.mp3,rock
8 | ./rock/rock.00035.mp3,rock
9 | ./rock/rock.00095.mp3,rock
10 | ./rock/rock.00088.mp3,rock
11 | ./rock/rock.00048.mp3,rock
12 | ./rock/rock.00009.mp3,rock
13 | ./rock/rock.00036.mp3,rock
14 | ./rock/rock.00032.mp3,rock
15 | ./rock/rock.00019.mp3,rock
16 | ./rock/rock.00042.mp3,rock
17 | ./rock/rock.00003.mp3,rock
18 | ./rock/rock.00061.mp3,rock
19 | ./rock/rock.00013.mp3,rock
20 | ./rock/rock.00038.mp3,rock
21 | ./rock/rock.00054.mp3,rock
22 | ./rock/rock.00014.mp3,rock
23 | ./rock/rock.00004.mp3,rock
24 | ./rock/rock.00091.mp3,rock
25 | ./rock/rock.00025.mp3,rock
26 | ./rock/rock.00086.mp3,rock
27 | ./rock/rock.00090.mp3,rock
28 | ./rock/rock.00046.mp3,rock
29 | ./rock/rock.00075.mp3,rock
30 | ./rock/rock.00026.mp3,rock
31 | ./rock/rock.00049.mp3,rock
32 | ./rock/rock.00093.mp3,rock
33 | ./rock/rock.00001.mp3,rock
34 | ./rock/rock.00099.mp3,rock
35 | ./rock/rock.00010.mp3,rock
36 | ./rock/rock.00081.mp3,rock
37 | ./rock/rock.00089.mp3,rock
38 | ./rock/rock.00016.mp3,rock
39 | ./rock/rock.00012.mp3,rock
40 | ./rock/rock.00069.mp3,rock
41 | ./rock/rock.00083.mp3,rock
42 | ./rock/rock.00043.mp3,rock
43 | ./rock/rock.00062.mp3,rock
44 | ./rock/rock.00073.mp3,rock
45 | ./rock/rock.00060.mp3,rock
46 | ./rock/rock.00056.mp3,rock
47 | ./rock/rock.00023.mp3,rock
48 | ./rock/rock.00077.mp3,rock
49 | ./rock/rock.00041.mp3,rock
50 | ./rock/rock.00015.mp3,rock
51 | ./rock/rock.00033.mp3,rock
52 | ./rock/rock.00027.mp3,rock
53 | ./rock/rock.00058.mp3,rock
54 | ./rock/rock.00094.mp3,rock
55 | ./rock/rock.00020.mp3,rock
56 | ./rock/rock.00017.mp3,rock
57 | ./rock/rock.00005.mp3,rock
58 | ./rock/rock.00031.mp3,rock
59 | ./rock/rock.00050.mp3,rock
60 | ./rock/rock.00024.mp3,rock
61 | ./rock/rock.00021.mp3,rock
62 | ./rock/rock.00018.mp3,rock
63 | ./rock/rock.00065.mp3,rock
64 | ./rock/rock.00087.mp3,rock
65 | ./rock/rock.00097.mp3,rock
66 | ./rock/rock.00000.mp3,rock
67 | ./rock/rock.00085.mp3,rock
68 | ./rock/rock.00082.mp3,rock
69 | ./rock/rock.00007.mp3,rock
70 | ./rock/rock.00002.mp3,rock
71 | ./rock/rock.00037.mp3,rock
72 | ./rock/rock.00059.mp3,rock
73 | ./rock/rock.00080.mp3,rock
74 | ./rock/rock.00039.mp3,rock
75 | ./rock/rock.00072.mp3,rock
76 | ./rock/rock.00022.mp3,rock
77 | ./rock/rock.00079.mp3,rock
78 | ./rock/rock.00047.mp3,rock
79 | ./rock/rock.00006.mp3,rock
80 | ./rock/rock.00008.mp3,rock
81 | ./rock/rock.00040.mp3,rock
82 | ./rock/rock.00096.mp3,rock
83 | ./rock/rock.00045.mp3,rock
84 | ./rock/rock.00029.mp3,rock
85 | ./rock/rock.00030.mp3,rock
86 | ./rock/rock.00064.mp3,rock
87 | ./rock/rock.00063.mp3,rock
88 | ./rock/rock.00074.mp3,rock
89 | ./rock/rock.00055.mp3,rock
90 | ./rock/rock.00068.mp3,rock
91 | ./rock/rock.00067.mp3,rock
92 | ./rock/rock.00044.mp3,rock
93 | ./rock/rock.00070.mp3,rock
94 | ./rock/rock.00066.mp3,rock
95 | ./rock/rock.00092.mp3,rock
96 | ./rock/rock.00098.mp3,rock
97 | ./rock/rock.00078.mp3,rock
98 | ./rock/rock.00034.mp3,rock
99 | ./rock/rock.00071.mp3,rock
100 | ./rock/rock.00011.mp3,rock
101 | ./hiphop/hiphop.00096.mp3,hiphop
102 | ./hiphop/hiphop.00023.mp3,hiphop
103 | ./hiphop/hiphop.00097.mp3,hiphop
104 | ./hiphop/hiphop.00090.mp3,hiphop
105 | ./hiphop/hiphop.00053.mp3,hiphop
106 | ./hiphop/hiphop.00085.mp3,hiphop
107 | ./hiphop/hiphop.00073.mp3,hiphop
108 | ./hiphop/hiphop.00007.mp3,hiphop
109 | ./hiphop/hiphop.00036.mp3,hiphop
110 | ./hiphop/hiphop.00010.mp3,hiphop
111 | ./hiphop/hiphop.00071.mp3,hiphop
112 | ./hiphop/hiphop.00047.mp3,hiphop
113 | ./hiphop/hiphop.00035.mp3,hiphop
114 | ./hiphop/hiphop.00066.mp3,hiphop
115 | ./hiphop/hiphop.00052.mp3,hiphop
116 | ./hiphop/hiphop.00095.mp3,hiphop
117 | ./hiphop/hiphop.00046.mp3,hiphop
118 | ./hiphop/hiphop.00089.mp3,hiphop
119 | ./hiphop/hiphop.00029.mp3,hiphop
120 | ./hiphop/hiphop.00025.mp3,hiphop
121 | ./hiphop/hiphop.00088.mp3,hiphop
122 | ./hiphop/hiphop.00100.mp3,hiphop
123 | ./hiphop/hiphop.00058.mp3,hiphop
124 | ./hiphop/hiphop.00050.mp3,hiphop
125 | ./hiphop/hiphop.00051.mp3,hiphop
126 | ./hiphop/hiphop.00057.mp3,hiphop
127 | ./hiphop/hiphop.00080.mp3,hiphop
128 | ./hiphop/hiphop.00032.mp3,hiphop
129 | ./hiphop/hiphop.00013.mp3,hiphop
130 | ./hiphop/hiphop.00011.mp3,hiphop
131 | ./hiphop/hiphop.00092.mp3,hiphop
132 | ./hiphop/hiphop.00028.mp3,hiphop
133 | ./hiphop/hiphop.00000.mp3,hiphop
134 | ./hiphop/hiphop.00079.mp3,hiphop
135 | ./hiphop/hiphop.00001.mp3,hiphop
136 | ./hiphop/hiphop.00072.mp3,hiphop
137 | ./hiphop/hiphop.00049.mp3,hiphop
138 | ./hiphop/hiphop.00087.mp3,hiphop
139 | ./hiphop/hiphop.00041.mp3,hiphop
140 | ./hiphop/hiphop.00083.mp3,hiphop
141 | ./hiphop/hiphop.00059.mp3,hiphop
142 | ./hiphop/hiphop.00063.mp3,hiphop
143 | ./hiphop/hiphop.00048.mp3,hiphop
144 | ./hiphop/hiphop.00039.mp3,hiphop
145 | ./hiphop/hiphop.00009.mp3,hiphop
146 | ./hiphop/hiphop.00008.mp3,hiphop
147 | ./hiphop/hiphop.00101.mp3,hiphop
148 | ./hiphop/hiphop.00068.mp3,hiphop
149 | ./hiphop/hiphop.00031.mp3,hiphop
150 | ./hiphop/hiphop.00061.mp3,hiphop
151 | ./hiphop/hiphop.00024.mp3,hiphop
152 | ./hiphop/hiphop.00081.mp3,hiphop
153 | ./hiphop/hiphop.00054.mp3,hiphop
154 | ./hiphop/hiphop.00094.mp3,hiphop
155 | ./hiphop/hiphop.00075.mp3,hiphop
156 | ./hiphop/hiphop.00042.mp3,hiphop
157 | ./hiphop/hiphop.00078.mp3,hiphop
158 | ./hiphop/hiphop.00027.mp3,hiphop
159 | ./hiphop/hiphop.00026.mp3,hiphop
160 | ./hiphop/hiphop.00074.mp3,hiphop
161 | ./hiphop/hiphop.00004.mp3,hiphop
162 | ./hiphop/hiphop.00060.mp3,hiphop
163 | ./hiphop/hiphop.00043.mp3,hiphop
164 | ./hiphop/hiphop.00014.mp3,hiphop
165 | ./hiphop/hiphop.00018.mp3,hiphop
166 | ./hiphop/hiphop.00062.mp3,hiphop
167 | ./hiphop/hiphop.00076.mp3,hiphop
168 | ./hiphop/hiphop.00020.mp3,hiphop
169 | ./hiphop/hiphop.00064.mp3,hiphop
170 | ./hiphop/hiphop.00055.mp3,hiphop
171 | ./hiphop/hiphop.00017.mp3,hiphop
172 | ./hiphop/hiphop.00070.mp3,hiphop
173 | ./hiphop/hiphop.00033.mp3,hiphop
174 | ./hiphop/hiphop.00040.mp3,hiphop
175 | ./hiphop/hiphop.00012.mp3,hiphop
176 | ./hiphop/hiphop.00002.mp3,hiphop
177 | ./hiphop/hiphop.00015.mp3,hiphop
178 | ./hiphop/hiphop.00077.mp3,hiphop
179 | ./hiphop/hiphop.00044.mp3,hiphop
180 | ./hiphop/hiphop.00056.mp3,hiphop
181 | ./hiphop/hiphop.00038.mp3,hiphop
182 | ./hiphop/hiphop.00086.mp3,hiphop
183 | ./hiphop/hiphop.00091.mp3,hiphop
184 | ./hiphop/hiphop.00037.mp3,hiphop
185 | ./hiphop/hiphop.00016.mp3,hiphop
186 | ./hiphop/hiphop.00067.mp3,hiphop
187 | ./hiphop/hiphop.00082.mp3,hiphop
188 | ./hiphop/hiphop.00069.mp3,hiphop
189 | ./hiphop/hiphop.00005.mp3,hiphop
190 | ./hiphop/hiphop.00034.mp3,hiphop
191 | ./hiphop/hiphop.00065.mp3,hiphop
192 | ./hiphop/hiphop.00084.mp3,hiphop
193 | ./hiphop/hiphop.00021.mp3,hiphop
194 | ./hiphop/hiphop.00098.mp3,hiphop
195 | ./hiphop/hiphop.00045.mp3,hiphop
196 | ./hiphop/hiphop.00093.mp3,hiphop
197 | ./hiphop/hiphop.00099.mp3,hiphop
198 | ./hiphop/hiphop.00006.mp3,hiphop
199 | ./hiphop/hiphop.00003.mp3,hiphop
200 | ./hiphop/hiphop.00022.mp3,hiphop
201 | ./disco/disco.00047.mp3,disco
202 | ./disco/disco.00066.mp3,disco
203 | ./disco/disco.00027.mp3,disco
204 | ./disco/disco.00046.mp3,disco
205 | ./disco/disco.00067.mp3,disco
206 | ./disco/disco.00052.mp3,disco
207 | ./disco/disco.00086.mp3,disco
208 | ./disco/disco.00026.mp3,disco
209 | ./disco/disco.00060.mp3,disco
210 | ./disco/disco.00096.mp3,disco
211 | ./disco/disco.00076.mp3,disco
212 | ./disco/disco.00058.mp3,disco
213 | ./disco/disco.00097.mp3,disco
214 | ./disco/disco.00002.mp3,disco
215 | ./disco/disco.00032.mp3,disco
216 | ./disco/disco.00024.mp3,disco
217 | ./disco/disco.00091.mp3,disco
218 | ./disco/disco.00006.mp3,disco
219 | ./disco/disco.00078.mp3,disco
220 | ./disco/disco.00092.mp3,disco
221 | ./disco/disco.00020.mp3,disco
222 | ./disco/disco.00073.mp3,disco
223 | ./disco/disco.00057.mp3,disco
224 | ./disco/disco.00072.mp3,disco
225 | ./disco/disco.00011.mp3,disco
226 | ./disco/disco.00065.mp3,disco
227 | ./disco/disco.00068.mp3,disco
228 | ./disco/disco.00033.mp3,disco
229 | ./disco/disco.00083.mp3,disco
230 | ./disco/disco.00085.mp3,disco
231 | ./disco/disco.00093.mp3,disco
232 | ./disco/disco.00036.mp3,disco
233 | ./disco/disco.00037.mp3,disco
234 | ./disco/disco.00071.mp3,disco
235 | ./disco/disco.00088.mp3,disco
236 | ./disco/disco.00090.mp3,disco
237 | ./disco/disco.00008.mp3,disco
238 | ./disco/disco.00098.mp3,disco
239 | ./disco/disco.00022.mp3,disco
240 | ./disco/disco.00001.mp3,disco
241 | ./disco/disco.00061.mp3,disco
242 | ./disco/disco.00041.mp3,disco
243 | ./disco/disco.00082.mp3,disco
244 | ./disco/disco.00074.mp3,disco
245 | ./disco/disco.00042.mp3,disco
246 | ./disco/disco.00012.mp3,disco
247 | ./disco/disco.00000.mp3,disco
248 | ./disco/disco.00080.mp3,disco
249 | ./disco/disco.00095.mp3,disco
250 | ./disco/disco.00051.mp3,disco
251 | ./disco/disco.00040.mp3,disco
252 | ./disco/disco.00069.mp3,disco
253 | ./disco/disco.00028.mp3,disco
254 | ./disco/disco.00016.mp3,disco
255 | ./disco/disco.00062.mp3,disco
256 | ./disco/disco.00014.mp3,disco
257 | ./disco/disco.00007.mp3,disco
258 | ./disco/disco.00087.mp3,disco
259 | ./disco/disco.00049.mp3,disco
260 | ./disco/disco.00029.mp3,disco
261 | ./disco/disco.00018.mp3,disco
262 | ./disco/disco.00081.mp3,disco
263 | ./disco/disco.00039.mp3,disco
264 | ./disco/disco.00025.mp3,disco
265 | ./disco/disco.00050.mp3,disco
266 | ./disco/disco.00059.mp3,disco
267 | ./disco/disco.00015.mp3,disco
268 | ./disco/disco.00004.mp3,disco
269 | ./disco/disco.00070.mp3,disco
270 | ./disco/disco.00079.mp3,disco
271 | ./disco/disco.00043.mp3,disco
272 | ./disco/disco.00094.mp3,disco
273 | ./disco/disco.00064.mp3,disco
274 | ./disco/disco.00099.mp3,disco
275 | ./disco/disco.00034.mp3,disco
276 | ./disco/disco.00075.mp3,disco
277 | ./disco/disco.00013.mp3,disco
278 | ./disco/disco.00077.mp3,disco
279 | ./disco/disco.00045.mp3,disco
280 | ./disco/disco.00023.mp3,disco
281 | ./disco/disco.00009.mp3,disco
282 | ./disco/disco.00035.mp3,disco
283 | ./disco/disco.00031.mp3,disco
284 | ./disco/disco.00003.mp3,disco
285 | ./disco/disco.00089.mp3,disco
286 | ./disco/disco.00010.mp3,disco
287 | ./disco/disco.00063.mp3,disco
288 | ./disco/disco.00019.mp3,disco
289 | ./disco/disco.00054.mp3,disco
290 | ./disco/disco.00030.mp3,disco
291 | ./disco/disco.00048.mp3,disco
292 | ./disco/disco.00055.mp3,disco
293 | ./disco/disco.00044.mp3,disco
294 | ./disco/disco.00053.mp3,disco
295 | ./disco/disco.00017.mp3,disco
296 | ./disco/disco.00056.mp3,disco
297 | ./disco/disco.00084.mp3,disco
298 | ./disco/disco.00038.mp3,disco
299 | ./disco/disco.00021.mp3,disco
300 | ./disco/disco.00005.mp3,disco
301 | ./metal/metal.00058.mp3,metal
302 | ./metal/metal.00053.mp3,metal
303 | ./metal/metal.00059.mp3,metal
304 | ./metal/metal.00043.mp3,metal
305 | ./metal/metal.00086.mp3,metal
306 | ./metal/metal.00006.mp3,metal
307 | ./metal/metal.00035.mp3,metal
308 | ./metal/metal.00028.mp3,metal
309 | ./metal/metal.00048.mp3,metal
310 | ./metal/metal.00020.mp3,metal
311 | ./metal/metal.00052.mp3,metal
312 | ./metal/metal.00071.mp3,metal
313 | ./metal/metal.00080.mp3,metal
314 | ./metal/metal.00091.mp3,metal
315 | ./metal/metal.00065.mp3,metal
316 | ./metal/metal.00025.mp3,metal
317 | ./metal/metal.00083.mp3,metal
318 | ./metal/metal.00013.mp3,metal
319 | ./metal/metal.00030.mp3,metal
320 | ./metal/metal.00019.mp3,metal
321 | ./metal/metal.00072.mp3,metal
322 | ./metal/metal.00050.mp3,metal
323 | ./metal/metal.00024.mp3,metal
324 | ./metal/metal.00060.mp3,metal
325 | ./metal/metal.00045.mp3,metal
326 | ./metal/metal.00026.mp3,metal
327 | ./metal/metal.00081.mp3,metal
328 | ./metal/metal.00005.mp3,metal
329 | ./metal/metal.00015.mp3,metal
330 | ./metal/metal.00051.mp3,metal
331 | ./metal/metal.00097.mp3,metal
332 | ./metal/metal.00016.mp3,metal
333 | ./metal/metal.00036.mp3,metal
334 | ./metal/metal.00057.mp3,metal
335 | ./metal/metal.00040.mp3,metal
336 | ./metal/metal.00011.mp3,metal
337 | ./metal/metal.00032.mp3,metal
338 | ./metal/metal.00087.mp3,metal
339 | ./metal/metal.00061.mp3,metal
340 | ./metal/metal.00085.mp3,metal
341 | ./metal/metal.00004.mp3,metal
342 | ./metal/metal.00009.mp3,metal
343 | ./metal/metal.00038.mp3,metal
344 | ./metal/metal.00075.mp3,metal
345 | ./metal/metal.00039.mp3,metal
346 | ./metal/metal.00031.mp3,metal
347 | ./metal/metal.00084.mp3,metal
348 | ./metal/metal.00070.mp3,metal
349 | ./metal/metal.00055.mp3,metal
350 | ./metal/metal.00062.mp3,metal
351 | ./metal/metal.00041.mp3,metal
352 | ./metal/metal.00023.mp3,metal
353 | ./metal/metal.00090.mp3,metal
354 | ./metal/metal.00069.mp3,metal
355 | ./metal/metal.00079.mp3,metal
356 | ./metal/metal.00001.mp3,metal
357 | ./metal/metal.00088.mp3,metal
358 | ./metal/metal.00018.mp3,metal
359 | ./metal/metal.00063.mp3,metal
360 | ./metal/metal.00049.mp3,metal
361 | ./metal/metal.00096.mp3,metal
362 | ./metal/metal.00056.mp3,metal
363 | ./metal/metal.00077.mp3,metal
364 | ./metal/metal.00002.mp3,metal
365 | ./metal/metal.00010.mp3,metal
366 | ./metal/metal.00003.mp3,metal
367 | ./metal/metal.00037.mp3,metal
368 | ./metal/metal.00017.mp3,metal
369 | ./metal/metal.00073.mp3,metal
370 | ./metal/metal.00078.mp3,metal
371 | ./metal/metal.00008.mp3,metal
372 | ./metal/metal.00076.mp3,metal
373 | ./metal/metal.00022.mp3,metal
374 | ./metal/metal.00092.mp3,metal
375 | ./metal/metal.00042.mp3,metal
376 | ./metal/metal.00033.mp3,metal
377 | ./metal/metal.00074.mp3,metal
378 | ./metal/metal.00094.mp3,metal
379 | ./metal/metal.00027.mp3,metal
380 | ./metal/metal.00054.mp3,metal
381 | ./metal/metal.00064.mp3,metal
382 | ./metal/metal.00068.mp3,metal
383 | ./metal/metal.00089.mp3,metal
384 | ./metal/metal.00044.mp3,metal
385 | ./metal/metal.00047.mp3,metal
386 | ./metal/metal.00066.mp3,metal
387 | ./metal/metal.00000.mp3,metal
388 | ./metal/metal.00067.mp3,metal
389 | ./metal/metal.00099.mp3,metal
390 | ./metal/metal.00093.mp3,metal
391 | ./metal/metal.00046.mp3,metal
392 | ./metal/metal.00082.mp3,metal
393 | ./metal/metal.00012.mp3,metal
394 | ./metal/metal.00014.mp3,metal
395 | ./metal/metal.00034.mp3,metal
396 | ./metal/metal.00021.mp3,metal
397 | ./metal/metal.00007.mp3,metal
398 | ./metal/metal.00098.mp3,metal
399 | ./metal/metal.00029.mp3,metal
400 | ./metal/metal.00100.mp3,metal
401 | ./jazz/jazz.00026.mp3,jazz
402 | ./jazz/jazz.00075.mp3,jazz
403 | ./jazz/jazz.00030.mp3,jazz
404 | ./jazz/jazz.00080.mp3,jazz
405 | ./jazz/jazz.00042.mp3,jazz
406 | ./jazz/jazz.00073.mp3,jazz
407 | ./jazz/jazz.00014.mp3,jazz
408 | ./jazz/jazz.00015.mp3,jazz
409 | ./jazz/jazz.00007.mp3,jazz
410 | ./jazz/jazz.00059.mp3,jazz
411 | ./jazz/jazz.00021.mp3,jazz
412 | ./jazz/jazz.00003.mp3,jazz
413 | ./jazz/jazz.00091.mp3,jazz
414 | ./jazz/jazz.00052.mp3,jazz
415 | ./jazz/jazz.00041.mp3,jazz
416 | ./jazz/jazz.00049.mp3,jazz
417 | ./jazz/jazz.00088.mp3,jazz
418 | ./jazz/jazz.00022.mp3,jazz
419 | ./jazz/jazz.00004.mp3,jazz
420 | ./jazz/jazz.00067.mp3,jazz
421 | ./jazz/jazz.00043.mp3,jazz
422 | ./jazz/jazz.00082.mp3,jazz
423 | ./jazz/jazz.00083.mp3,jazz
424 | ./jazz/jazz.00074.mp3,jazz
425 | ./jazz/jazz.00077.mp3,jazz
426 | ./jazz/jazz.00016.mp3,jazz
427 | ./jazz/jazz.00098.mp3,jazz
428 | ./jazz/jazz.00000.mp3,jazz
429 | ./jazz/jazz.00096.mp3,jazz
430 | ./jazz/jazz.00097.mp3,jazz
431 | ./jazz/jazz.00090.mp3,jazz
432 | ./jazz/jazz.00034.mp3,jazz
433 | ./jazz/jazz.00028.mp3,jazz
434 | ./jazz/jazz.00010.mp3,jazz
435 | ./jazz/jazz.00070.mp3,jazz
436 | ./jazz/jazz.00093.mp3,jazz
437 | ./jazz/jazz.00008.mp3,jazz
438 | ./jazz/jazz.00055.mp3,jazz
439 | ./jazz/jazz.00094.mp3,jazz
440 | ./jazz/jazz.00009.mp3,jazz
441 | ./jazz/jazz.00085.mp3,jazz
442 | ./jazz/jazz.00063.mp3,jazz
443 | ./jazz/jazz.00011.mp3,jazz
444 | ./jazz/jazz.00086.mp3,jazz
445 | ./jazz/jazz.00047.mp3,jazz
446 | ./jazz/jazz.00061.mp3,jazz
447 | ./jazz/jazz.00056.mp3,jazz
448 | ./jazz/jazz.00078.mp3,jazz
449 | ./jazz/jazz.00054.mp3,jazz
450 | ./jazz/jazz.00072.mp3,jazz
451 | ./jazz/jazz.00020.mp3,jazz
452 | ./jazz/jazz.00039.mp3,jazz
453 | ./jazz/jazz.00019.mp3,jazz
454 | ./jazz/jazz.00071.mp3,jazz
455 | ./jazz/jazz.00065.mp3,jazz
456 | ./jazz/jazz.00081.mp3,jazz
457 | ./jazz/jazz.00035.mp3,jazz
458 | ./jazz/jazz.00057.mp3,jazz
459 | ./jazz/jazz.00023.mp3,jazz
460 | ./jazz/jazz.00001.mp3,jazz
461 | ./jazz/jazz.00068.mp3,jazz
462 | ./jazz/jazz.00048.mp3,jazz
463 | ./jazz/jazz.00002.mp3,jazz
464 | ./jazz/jazz.00087.mp3,jazz
465 | ./jazz/jazz.00053.mp3,jazz
466 | ./jazz/jazz.00069.mp3,jazz
467 | ./jazz/jazz.00095.mp3,jazz
468 | ./jazz/jazz.00060.mp3,jazz
469 | ./jazz/jazz.00089.mp3,jazz
470 | ./jazz/jazz.00084.mp3,jazz
471 | ./jazz/jazz.00058.mp3,jazz
472 | ./jazz/jazz.00064.mp3,jazz
473 | ./jazz/jazz.00006.mp3,jazz
474 | ./jazz/jazz.00099.mp3,jazz
475 | ./jazz/jazz.00018.mp3,jazz
476 | ./jazz/jazz.00031.mp3,jazz
477 | ./jazz/jazz.00044.mp3,jazz
478 | ./jazz/jazz.00032.mp3,jazz
479 | ./jazz/jazz.00038.mp3,jazz
480 | ./jazz/jazz.00033.mp3,jazz
481 | ./jazz/jazz.00051.mp3,jazz
482 | ./jazz/jazz.00005.mp3,jazz
483 | ./jazz/jazz.00012.mp3,jazz
484 | ./jazz/jazz.00062.mp3,jazz
485 | ./jazz/jazz.00029.mp3,jazz
486 | ./jazz/jazz.00025.mp3,jazz
487 | ./jazz/jazz.00024.mp3,jazz
488 | ./jazz/jazz.00027.mp3,jazz
489 | ./jazz/jazz.00092.mp3,jazz
490 | ./jazz/jazz.00076.mp3,jazz
491 | ./jazz/jazz.00046.mp3,jazz
492 | ./jazz/jazz.00037.mp3,jazz
493 | ./jazz/jazz.00036.mp3,jazz
494 | ./jazz/jazz.00013.mp3,jazz
495 | ./jazz/jazz.00066.mp3,jazz
496 | ./jazz/jazz.00079.mp3,jazz
497 | ./jazz/jazz.00017.mp3,jazz
498 | ./jazz/jazz.00040.mp3,jazz
499 | ./jazz/jazz.00045.mp3,jazz
500 | ./jazz/jazz.00050.mp3,jazz
501 | ./classical/classical.00070.mp3,classical
502 | ./classical/classical.00006.mp3,classical
503 | ./classical/classical.00045.mp3,classical
504 | ./classical/classical.00065.mp3,classical
505 | ./classical/classical.00077.mp3,classical
506 | ./classical/classical.00044.mp3,classical
507 | ./classical/classical.00082.mp3,classical
508 | ./classical/classical.00053.mp3,classical
509 | ./classical/classical.00021.mp3,classical
510 | ./classical/classical.00092.mp3,classical
511 | ./classical/classical.00078.mp3,classical
512 | ./classical/classical.00054.mp3,classical
513 | ./classical/classical.00074.mp3,classical
514 | ./classical/classical.00000.mp3,classical
515 | ./classical/classical.00089.mp3,classical
516 | ./classical/classical.00024.mp3,classical
517 | ./classical/classical.00020.mp3,classical
518 | ./classical/classical.00017.mp3,classical
519 | ./classical/classical.00069.mp3,classical
520 | ./classical/classical.00026.mp3,classical
521 | ./classical/classical.00018.mp3,classical
522 | ./classical/classical.00029.mp3,classical
523 | ./classical/classical.00052.mp3,classical
524 | ./classical/classical.00094.mp3,classical
525 | ./classical/classical.00073.mp3,classical
526 | ./classical/classical.00013.mp3,classical
527 | ./classical/classical.00022.mp3,classical
528 | ./classical/classical.00056.mp3,classical
529 | ./classical/classical.00075.mp3,classical
530 | ./classical/classical.00007.mp3,classical
531 | ./classical/classical.00050.mp3,classical
532 | ./classical/classical.00047.mp3,classical
533 | ./classical/classical.00025.mp3,classical
534 | ./classical/classical.00083.mp3,classical
535 | ./classical/classical.00060.mp3,classical
536 | ./classical/classical.00014.mp3,classical
537 | ./classical/classical.00057.mp3,classical
538 | ./classical/classical.00058.mp3,classical
539 | ./classical/classical.00027.mp3,classical
540 | ./classical/classical.00091.mp3,classical
541 | ./classical/classical.00086.mp3,classical
542 | ./classical/classical.00068.mp3,classical
543 | ./classical/classical.00031.mp3,classical
544 | ./classical/classical.00038.mp3,classical
545 | ./classical/classical.00071.mp3,classical
546 | ./classical/classical.00098.mp3,classical
547 | ./classical/classical.00011.mp3,classical
548 | ./classical/classical.00061.mp3,classical
549 | ./classical/classical.00002.mp3,classical
550 | ./classical/classical.00030.mp3,classical
551 | ./classical/classical.00093.mp3,classical
552 | ./classical/classical.00087.mp3,classical
553 | ./classical/classical.00096.mp3,classical
554 | ./classical/classical.00037.mp3,classical
555 | ./classical/classical.00036.mp3,classical
556 | ./classical/classical.00095.mp3,classical
557 | ./classical/classical.00028.mp3,classical
558 | ./classical/classical.00019.mp3,classical
559 | ./classical/classical.00012.mp3,classical
560 | ./classical/classical.00035.mp3,classical
561 | ./classical/classical.00016.mp3,classical
562 | ./classical/classical.00010.mp3,classical
563 | ./classical/classical.00040.mp3,classical
564 | ./classical/classical.00043.mp3,classical
565 | ./classical/classical.00062.mp3,classical
566 | ./classical/classical.00059.mp3,classical
567 | ./classical/classical.00079.mp3,classical
568 | ./classical/classical.00088.mp3,classical
569 | ./classical/classical.00097.mp3,classical
570 | ./classical/classical.00051.mp3,classical
571 | ./classical/classical.00041.mp3,classical
572 | ./classical/classical.00085.mp3,classical
573 | ./classical/classical.00033.mp3,classical
574 | ./classical/classical.00004.mp3,classical
575 | ./classical/classical.00048.mp3,classical
576 | ./classical/classical.00049.mp3,classical
577 | ./classical/classical.00084.mp3,classical
578 | ./classical/classical.00023.mp3,classical
579 | ./classical/classical.00055.mp3,classical
580 | ./classical/classical.00003.mp3,classical
581 | ./classical/classical.00081.mp3,classical
582 | ./classical/classical.00080.mp3,classical
583 | ./classical/classical.00001.mp3,classical
584 | ./classical/classical.00032.mp3,classical
585 | ./classical/classical.00064.mp3,classical
586 | ./classical/classical.00063.mp3,classical
587 | ./classical/classical.00090.mp3,classical
588 | ./classical/classical.00009.mp3,classical
589 | ./classical/classical.00099.mp3,classical
590 | ./classical/classical.00066.mp3,classical
591 | ./classical/classical.00072.mp3,classical
592 | ./classical/classical.00039.mp3,classical
593 | ./classical/classical.00034.mp3,classical
594 | ./classical/classical.00046.mp3,classical
595 | ./classical/classical.00008.mp3,classical
596 | ./classical/classical.00005.mp3,classical
597 | ./classical/classical.00076.mp3,classical
598 | ./classical/classical.00042.mp3,classical
599 | ./classical/classical.00015.mp3,classical
600 | ./classical/classical.00067.mp3,classical
601 | ./reggae/reggae.00073.mp3,reggae
602 | ./reggae/reggae.00044.mp3,reggae
603 | ./reggae/reggae.00014.mp3,reggae
604 | ./reggae/reggae.00030.mp3,reggae
605 | ./reggae/reggae.00068.mp3,reggae
606 | ./reggae/reggae.00027.mp3,reggae
607 | ./reggae/reggae.00034.mp3,reggae
608 | ./reggae/reggae.00066.mp3,reggae
609 | ./reggae/reggae.00038.mp3,reggae
610 | ./reggae/reggae.00007.mp3,reggae
611 | ./reggae/reggae.00063.mp3,reggae
612 | ./reggae/reggae.00074.mp3,reggae
613 | ./reggae/reggae.00090.mp3,reggae
614 | ./reggae/reggae.00062.mp3,reggae
615 | ./reggae/reggae.00086.mp3,reggae
616 | ./reggae/reggae.00021.mp3,reggae
617 | ./reggae/reggae.00033.mp3,reggae
618 | ./reggae/reggae.00058.mp3,reggae
619 | ./reggae/reggae.00029.mp3,reggae
620 | ./reggae/reggae.00067.mp3,reggae
621 | ./reggae/reggae.00023.mp3,reggae
622 | ./reggae/reggae.00022.mp3,reggae
623 | ./reggae/reggae.00028.mp3,reggae
624 | ./reggae/reggae.00025.mp3,reggae
625 | ./reggae/reggae.00024.mp3,reggae
626 | ./reggae/reggae.00011.mp3,reggae
627 | ./reggae/reggae.00078.mp3,reggae
628 | ./reggae/reggae.00080.mp3,reggae
629 | ./reggae/reggae.00057.mp3,reggae
630 | ./reggae/reggae.00082.mp3,reggae
631 | ./reggae/reggae.00016.mp3,reggae
632 | ./reggae/reggae.00079.mp3,reggae
633 | ./reggae/reggae.00039.mp3,reggae
634 | ./reggae/reggae.00008.mp3,reggae
635 | ./reggae/reggae.00012.mp3,reggae
636 | ./reggae/reggae.00056.mp3,reggae
637 | ./reggae/reggae.00059.mp3,reggae
638 | ./reggae/reggae.00083.mp3,reggae
639 | ./reggae/reggae.00010.mp3,reggae
640 | ./reggae/reggae.00052.mp3,reggae
641 | ./reggae/reggae.00095.mp3,reggae
642 | ./reggae/reggae.00003.mp3,reggae
643 | ./reggae/reggae.00001.mp3,reggae
644 | ./reggae/reggae.00075.mp3,reggae
645 | ./reggae/reggae.00065.mp3,reggae
646 | ./reggae/reggae.00060.mp3,reggae
647 | ./reggae/reggae.00081.mp3,reggae
648 | ./reggae/reggae.00048.mp3,reggae
649 | ./reggae/reggae.00019.mp3,reggae
650 | ./reggae/reggae.00045.mp3,reggae
651 | ./reggae/reggae.00091.mp3,reggae
652 | ./reggae/reggae.00097.mp3,reggae
653 | ./reggae/reggae.00037.mp3,reggae
654 | ./reggae/reggae.00018.mp3,reggae
655 | ./reggae/reggae.00049.mp3,reggae
656 | ./reggae/reggae.00031.mp3,reggae
657 | ./reggae/reggae.00017.mp3,reggae
658 | ./reggae/reggae.00042.mp3,reggae
659 | ./reggae/reggae.00004.mp3,reggae
660 | ./reggae/reggae.00088.mp3,reggae
661 | ./reggae/reggae.00085.mp3,reggae
662 | ./reggae/reggae.00092.mp3,reggae
663 | ./reggae/reggae.00070.mp3,reggae
664 | ./reggae/reggae.00093.mp3,reggae
665 | ./reggae/reggae.00084.mp3,reggae
666 | ./reggae/reggae.00064.mp3,reggae
667 | ./reggae/reggae.00050.mp3,reggae
668 | ./reggae/reggae.00032.mp3,reggae
669 | ./reggae/reggae.00046.mp3,reggae
670 | ./reggae/reggae.00035.mp3,reggae
671 | ./reggae/reggae.00009.mp3,reggae
672 | ./reggae/reggae.00076.mp3,reggae
673 | ./reggae/reggae.00089.mp3,reggae
674 | ./reggae/reggae.00047.mp3,reggae
675 | ./reggae/reggae.00043.mp3,reggae
676 | ./reggae/reggae.00005.mp3,reggae
677 | ./reggae/reggae.00071.mp3,reggae
678 | ./reggae/reggae.00000.mp3,reggae
679 | ./reggae/reggae.00040.mp3,reggae
680 | ./reggae/reggae.00072.mp3,reggae
681 | ./reggae/reggae.00013.mp3,reggae
682 | ./reggae/reggae.00015.mp3,reggae
683 | ./reggae/reggae.00077.mp3,reggae
684 | ./reggae/reggae.00099.mp3,reggae
685 | ./reggae/reggae.00096.mp3,reggae
686 | ./reggae/reggae.00006.mp3,reggae
687 | ./reggae/reggae.00061.mp3,reggae
688 | ./reggae/reggae.00002.mp3,reggae
689 | ./reggae/reggae.00094.mp3,reggae
690 | ./reggae/reggae.00051.mp3,reggae
691 | ./reggae/reggae.00055.mp3,reggae
692 | ./reggae/reggae.00026.mp3,reggae
693 | ./reggae/reggae.00036.mp3,reggae
694 | ./reggae/reggae.00087.mp3,reggae
695 | ./reggae/reggae.00020.mp3,reggae
696 | ./reggae/reggae.00053.mp3,reggae
697 | ./reggae/reggae.00069.mp3,reggae
698 | ./reggae/reggae.00054.mp3,reggae
699 | ./reggae/reggae.00041.mp3,reggae
700 | ./reggae/reggae.00098.mp3,reggae
701 | ./pop/pop.00066.mp3,pop
702 | ./pop/pop.00002.mp3,pop
703 | ./pop/pop.00082.mp3,pop
704 | ./pop/pop.00093.mp3,pop
705 | ./pop/pop.00088.mp3,pop
706 | ./pop/pop.00025.mp3,pop
707 | ./pop/pop.00083.mp3,pop
708 | ./pop/pop.00061.mp3,pop
709 | ./pop/pop.00076.mp3,pop
710 | ./pop/pop.00069.mp3,pop
711 | ./pop/pop.00065.mp3,pop
712 | ./pop/pop.00053.mp3,pop
713 | ./pop/pop.00050.mp3,pop
714 | ./pop/pop.00058.mp3,pop
715 | ./pop/pop.00018.mp3,pop
716 | ./pop/pop.00052.mp3,pop
717 | ./pop/pop.00008.mp3,pop
718 | ./pop/pop.00094.mp3,pop
719 | ./pop/pop.00022.mp3,pop
720 | ./pop/pop.00028.mp3,pop
721 | ./pop/pop.00091.mp3,pop
722 | ./pop/pop.00090.mp3,pop
723 | ./pop/pop.00057.mp3,pop
724 | ./pop/pop.00005.mp3,pop
725 | ./pop/pop.00027.mp3,pop
726 | ./pop/pop.00011.mp3,pop
727 | ./pop/pop.00086.mp3,pop
728 | ./pop/pop.00074.mp3,pop
729 | ./pop/pop.00084.mp3,pop
730 | ./pop/pop.00099.mp3,pop
731 | ./pop/pop.00044.mp3,pop
732 | ./pop/pop.00024.mp3,pop
733 | ./pop/pop.00075.mp3,pop
734 | ./pop/pop.00095.mp3,pop
735 | ./pop/pop.00039.mp3,pop
736 | ./pop/pop.00045.mp3,pop
737 | ./pop/pop.00009.mp3,pop
738 | ./pop/pop.00034.mp3,pop
739 | ./pop/pop.00081.mp3,pop
740 | ./pop/pop.00042.mp3,pop
741 | ./pop/pop.00001.mp3,pop
742 | ./pop/pop.00004.mp3,pop
743 | ./pop/pop.00020.mp3,pop
744 | ./pop/pop.00068.mp3,pop
745 | ./pop/pop.00041.mp3,pop
746 | ./pop/pop.00089.mp3,pop
747 | ./pop/pop.00019.mp3,pop
748 | ./pop/pop.00012.mp3,pop
749 | ./pop/pop.00078.mp3,pop
750 | ./pop/pop.00051.mp3,pop
751 | ./pop/pop.00029.mp3,pop
752 | ./pop/pop.00033.mp3,pop
753 | ./pop/pop.00067.mp3,pop
754 | ./pop/pop.00055.mp3,pop
755 | ./pop/pop.00060.mp3,pop
756 | ./pop/pop.00097.mp3,pop
757 | ./pop/pop.00030.mp3,pop
758 | ./pop/pop.00015.mp3,pop
759 | ./pop/pop.00026.mp3,pop
760 | ./pop/pop.00092.mp3,pop
761 | ./pop/pop.00071.mp3,pop
762 | ./pop/pop.00096.mp3,pop
763 | ./pop/pop.00072.mp3,pop
764 | ./pop/pop.00064.mp3,pop
765 | ./pop/pop.00035.mp3,pop
766 | ./pop/pop.00007.mp3,pop
767 | ./pop/pop.00062.mp3,pop
768 | ./pop/pop.00000.mp3,pop
769 | ./pop/pop.00032.mp3,pop
770 | ./pop/pop.00037.mp3,pop
771 | ./pop/pop.00087.mp3,pop
772 | ./pop/pop.00063.mp3,pop
773 | ./pop/pop.00036.mp3,pop
774 | ./pop/pop.00046.mp3,pop
775 | ./pop/pop.00023.mp3,pop
776 | ./pop/pop.00049.mp3,pop
777 | ./pop/pop.00070.mp3,pop
778 | ./pop/pop.00043.mp3,pop
779 | ./pop/pop.00038.mp3,pop
780 | ./pop/pop.00080.mp3,pop
781 | ./pop/pop.00014.mp3,pop
782 | ./pop/pop.00040.mp3,pop
783 | ./pop/pop.00098.mp3,pop
784 | ./pop/pop.00013.mp3,pop
785 | ./pop/pop.00010.mp3,pop
786 | ./pop/pop.00047.mp3,pop
787 | ./pop/pop.00021.mp3,pop
788 | ./pop/pop.00048.mp3,pop
789 | ./pop/pop.00054.mp3,pop
790 | ./pop/pop.00085.mp3,pop
791 | ./pop/pop.00017.mp3,pop
792 | ./pop/pop.00031.mp3,pop
793 | ./pop/pop.00056.mp3,pop
794 | ./pop/pop.00006.mp3,pop
795 | ./pop/pop.00059.mp3,pop
796 | ./pop/pop.00077.mp3,pop
797 | ./pop/pop.00016.mp3,pop
798 | ./pop/pop.00079.mp3,pop
799 | ./pop/pop.00073.mp3,pop
800 | ./pop/pop.00003.mp3,pop
801 | ./blues/blues.00053.mp3,blues
802 | ./blues/blues.00039.mp3,blues
803 | ./blues/blues.00066.mp3,blues
804 | ./blues/blues.00011.mp3,blues
805 | ./blues/blues.00005.mp3,blues
806 | ./blues/blues.00000.mp3,blues
807 | ./blues/blues.00029.mp3,blues
808 | ./blues/blues.00086.mp3,blues
809 | ./blues/blues.00052.mp3,blues
810 | ./blues/blues.00051.mp3,blues
811 | ./blues/blues.00087.mp3,blues
812 | ./blues/blues.00034.mp3,blues
813 | ./blues/blues.00037.mp3,blues
814 | ./blues/blues.00045.mp3,blues
815 | ./blues/blues.00082.mp3,blues
816 | ./blues/blues.00028.mp3,blues
817 | ./blues/blues.00054.mp3,blues
818 | ./blues/blues.00032.mp3,blues
819 | ./blues/blues.00060.mp3,blues
820 | ./blues/blues.00081.mp3,blues
821 | ./blues/blues.00092.mp3,blues
822 | ./blues/blues.00030.mp3,blues
823 | ./blues/blues.00017.mp3,blues
824 | ./blues/blues.00036.mp3,blues
825 | ./blues/blues.00001.mp3,blues
826 | ./blues/blues.00004.mp3,blues
827 | ./blues/blues.00091.mp3,blues
828 | ./blues/blues.00093.mp3,blues
829 | ./blues/blues.00077.mp3,blues
830 | ./blues/blues.00064.mp3,blues
831 | ./blues/blues.00020.mp3,blues
832 | ./blues/blues.00084.mp3,blues
833 | ./blues/blues.00043.mp3,blues
834 | ./blues/blues.00035.mp3,blues
835 | ./blues/blues.00042.mp3,blues
836 | ./blues/blues.00022.mp3,blues
837 | ./blues/blues.00023.mp3,blues
838 | ./blues/blues.00059.mp3,blues
839 | ./blues/blues.00015.mp3,blues
840 | ./blues/blues.00072.mp3,blues
841 | ./blues/blues.00048.mp3,blues
842 | ./blues/blues.00047.mp3,blues
843 | ./blues/blues.00044.mp3,blues
844 | ./blues/blues.00078.mp3,blues
845 | ./blues/blues.00065.mp3,blues
846 | ./blues/blues.00056.mp3,blues
847 | ./blues/blues.00003.mp3,blues
848 | ./blues/blues.00019.mp3,blues
849 | ./blues/blues.00016.mp3,blues
850 | ./blues/blues.00097.mp3,blues
851 | ./blues/blues.00062.mp3,blues
852 | ./blues/blues.00040.mp3,blues
853 | ./blues/blues.00069.mp3,blues
854 | ./blues/blues.00006.mp3,blues
855 | ./blues/blues.00098.mp3,blues
856 | ./blues/blues.00057.mp3,blues
857 | ./blues/blues.00095.mp3,blues
858 | ./blues/blues.00099.mp3,blues
859 | ./blues/blues.00008.mp3,blues
860 | ./blues/blues.00013.mp3,blues
861 | ./blues/blues.00074.mp3,blues
862 | ./blues/blues.00096.mp3,blues
863 | ./blues/blues.00070.mp3,blues
864 | ./blues/blues.00088.mp3,blues
865 | ./blues/blues.00010.mp3,blues
866 | ./blues/blues.00038.mp3,blues
867 | ./blues/blues.00046.mp3,blues
868 | ./blues/blues.00073.mp3,blues
869 | ./blues/blues.00083.mp3,blues
870 | ./blues/blues.00007.mp3,blues
871 | ./blues/blues.00041.mp3,blues
872 | ./blues/blues.00049.mp3,blues
873 | ./blues/blues.00009.mp3,blues
874 | ./blues/blues.00090.mp3,blues
875 | ./blues/blues.00012.mp3,blues
876 | ./blues/blues.00085.mp3,blues
877 | ./blues/blues.00089.mp3,blues
878 | ./blues/blues.00050.mp3,blues
879 | ./blues/blues.00076.mp3,blues
880 | ./blues/blues.00080.mp3,blues
881 | ./blues/blues.00021.mp3,blues
882 | ./blues/blues.00061.mp3,blues
883 | ./blues/blues.00067.mp3,blues
884 | ./blues/blues.00063.mp3,blues
885 | ./blues/blues.00024.mp3,blues
886 | ./blues/blues.00031.mp3,blues
887 | ./blues/blues.00071.mp3,blues
888 | ./blues/blues.00027.mp3,blues
889 | ./blues/blues.00002.mp3,blues
890 | ./blues/blues.00014.mp3,blues
891 | ./blues/blues.00058.mp3,blues
892 | ./blues/blues.00025.mp3,blues
893 | ./blues/blues.00079.mp3,blues
894 | ./blues/blues.00094.mp3,blues
895 | ./blues/blues.00068.mp3,blues
896 | ./blues/blues.00026.mp3,blues
897 | ./blues/blues.00018.mp3,blues
898 | ./blues/blues.00055.mp3,blues
899 | ./blues/blues.00075.mp3,blues
900 | ./blues/blues.00033.mp3,blues
901 | ./country/country.00021.mp3,country
902 | ./country/country.00057.mp3,country
903 | ./country/country.00060.mp3,country
904 | ./country/country.00000.mp3,country
905 | ./country/country.00006.mp3,country
906 | ./country/country.00076.mp3,country
907 | ./country/country.00061.mp3,country
908 | ./country/country.00085.mp3,country
909 | ./country/country.00091.mp3,country
910 | ./country/country.00009.mp3,country
911 | ./country/country.00087.mp3,country
912 | ./country/country.00016.mp3,country
913 | ./country/country.00005.mp3,country
914 | ./country/country.00064.mp3,country
915 | ./country/country.00088.mp3,country
916 | ./country/country.00046.mp3,country
917 | ./country/country.00097.mp3,country
918 | ./country/country.00036.mp3,country
919 | ./country/country.00096.mp3,country
920 | ./country/country.00074.mp3,country
921 | ./country/country.00070.mp3,country
922 | ./country/country.00043.mp3,country
923 | ./country/country.00079.mp3,country
924 | ./country/country.00083.mp3,country
925 | ./country/country.00038.mp3,country
926 | ./country/country.00054.mp3,country
927 | ./country/country.00062.mp3,country
928 | ./country/country.00026.mp3,country
929 | ./country/country.00086.mp3,country
930 | ./country/country.00053.mp3,country
931 | ./country/country.00014.mp3,country
932 | ./country/country.00045.mp3,country
933 | ./country/country.00001.mp3,country
934 | ./country/country.00024.mp3,country
935 | ./country/country.00004.mp3,country
936 | ./country/country.00056.mp3,country
937 | ./country/country.00002.mp3,country
938 | ./country/country.00013.mp3,country
939 | ./country/country.00041.mp3,country
940 | ./country/country.00029.mp3,country
941 | ./country/country.00037.mp3,country
942 | ./country/country.00023.mp3,country
943 | ./country/country.00050.mp3,country
944 | ./country/country.00098.mp3,country
945 | ./country/country.00081.mp3,country
946 | ./country/country.00008.mp3,country
947 | ./country/country.00073.mp3,country
948 | ./country/country.00055.mp3,country
949 | ./country/country.00092.mp3,country
950 | ./country/country.00030.mp3,country
951 | ./country/country.00031.mp3,country
952 | ./country/country.00080.mp3,country
953 | ./country/country.00007.mp3,country
954 | ./country/country.00022.mp3,country
955 | ./country/country.00044.mp3,country
956 | ./country/country.00049.mp3,country
957 | ./country/country.00048.mp3,country
958 | ./country/country.00063.mp3,country
959 | ./country/country.00019.mp3,country
960 | ./country/country.00090.mp3,country
961 | ./country/country.00072.mp3,country
962 | ./country/country.00003.mp3,country
963 | ./country/country.00011.mp3,country
964 | ./country/country.00035.mp3,country
965 | ./country/country.00066.mp3,country
966 | ./country/country.00069.mp3,country
967 | ./country/country.00071.mp3,country
968 | ./country/country.00010.mp3,country
969 | ./country/country.00047.mp3,country
970 | ./country/country.00051.mp3,country
971 | ./country/country.00012.mp3,country
972 | ./country/country.00089.mp3,country
973 | ./country/country.00099.mp3,country
974 | ./country/country.00068.mp3,country
975 | ./country/country.00032.mp3,country
976 | ./country/country.00082.mp3,country
977 | ./country/country.00020.mp3,country
978 | ./country/country.00094.mp3,country
979 | ./country/country.00017.mp3,country
980 | ./country/country.00078.mp3,country
981 | ./country/country.00052.mp3,country
982 | ./country/country.00034.mp3,country
983 | ./country/country.00028.mp3,country
984 | ./country/country.00093.mp3,country
985 | ./country/country.00040.mp3,country
986 | ./country/country.00065.mp3,country
987 | ./country/country.00059.mp3,country
988 | ./country/country.00067.mp3,country
989 | ./country/country.00027.mp3,country
990 | ./country/country.00039.mp3,country
991 | ./country/country.00058.mp3,country
992 | ./country/country.00033.mp3,country
993 | ./country/country.00077.mp3,country
994 | ./country/country.00025.mp3,country
995 | ./country/country.00018.mp3,country
996 | ./country/country.00042.mp3,country
997 | ./country/country.00075.mp3,country
998 | ./country/country.00095.mp3,country
999 | ./country/country.00015.mp3,country
1000 | ./country/country.00084.mp3,country
1001 |
--------------------------------------------------------------------------------
/keras.json:
--------------------------------------------------------------------------------
1 | {
2 | "image_dim_ordering": "th",
3 | "epsilon": 1e-07,
4 | "floatx": "float32",
5 | "backend": "theano"
6 | }
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Keras>=1.2.1,<=1.3
2 | Theano==0.8.2
3 | scikit-learn>=0.17
4 | pandas
5 | librosa
6 | matplotlib
--------------------------------------------------------------------------------
/rp_extract.py:
--------------------------------------------------------------------------------
1 | '''
2 |
3 | RP_extract: Rhythm Patterns Audio Feature Extractor
4 |
5 | @author: 2014-2015 Alexander Schindler, Thomas Lidy
6 |
7 |
8 | Re-implementation by Alexander Schindler of RP_extract for Matlab
9 | Matlab version originally by Thomas Lidy, based on Musik Analysis Toolbox by Elias Pampalk
10 | ( see http://ifs.tuwien.ac.at/mir/downloads.html )
11 |
12 | Main function is rp_extract. See function definition and description for more information,
13 | or example usage in main function.
14 |
15 | Note: All required functions are provided by the two main scientific libraries numpy and scipy.
16 |
17 | Note: In case you alter the code to use transform2mel, librosa needs to be installed: pip install librosa
18 | '''
19 |
20 |
21 | import numpy as np
22 |
23 | from scipy import stats
24 | from scipy.fftpack import fft
25 | #from scipy.fftpack import rfft # Discrete Fourier transform of a real sequence.
26 | from scipy import interpolate
27 |
28 | # suppress numpy warnings (divide by 0 etc.)
29 | np.set_printoptions(suppress=True)
30 |
31 | # required for debugging
32 | np.set_printoptions(precision=8,
33 | threshold=10,
34 | suppress=True,
35 | linewidth=200,
36 | edgeitems=10)
37 |
38 |
39 | # INITIALIZATION: Constants & Mappings
40 |
41 | # Bark Scale
42 | bark = [100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500]
43 | n_bark_bands = len(bark)
44 |
45 | # copy the bark vector (using [:]) and add a 0 in front (to make calculations below easier)
46 | barks = bark[:]
47 | barks.insert(0,0)
48 |
49 | # Phone Scale
50 | phon = [3, 20, 40, 60, 80, 100, 101]
51 |
52 | # copy the bark vector (using [:]) and add a 0 in front (to make calculations below easier)
53 | phons = phon[:]
54 | phons.insert(0,0)
55 | phons = np.asarray(phons)
56 |
57 |
58 | # Loudness Curves
59 |
60 | eq_loudness = np.array([[55, 40, 32, 24, 19, 14, 10, 6, 4, 3, 2, 2, 0,-2,-5,-4, 0, 5, 10, 14, 25, 35],
61 | [66, 52, 43, 37, 32, 27, 23, 21, 20, 20, 20, 20,19,16,13,13,18, 22, 25, 30, 40, 50],
62 | [76, 64, 57, 51, 47, 43, 41, 41, 40, 40, 40,39.5,38,35,33,33,35, 41, 46, 50, 60, 70],
63 | [89, 79, 74, 70, 66, 63, 61, 60, 60, 60, 60, 59,56,53,52,53,56, 61, 65, 70, 80, 90],
64 | [103, 96, 92, 88, 85, 83, 81, 80, 80, 80, 80, 79,76,72,70,70,75, 79, 83, 87, 95,105],
65 | [118,110,107,105,103,102,101,100,100,100,100, 99,97,94,90,90,95,100,103,105,108,115]])
66 |
67 | loudn_freq = np.array([31.62, 50, 70.7, 100, 141.4, 200, 316.2, 500, 707.1, 1000, 1414, 1682, 2000, 2515, 3162, 3976, 5000, 7071, 10000, 11890, 14140, 15500])
68 |
69 | # We have the loudness values for the frequencies in loudn_freq
70 | # now we calculate in loudn_bark a matrix of loudness sensation values for the bark bands margins
71 |
72 | i = 0
73 | j = 0
74 |
75 | loudn_bark = np.zeros((eq_loudness.shape[0], len(bark)))
76 |
77 | for bsi in bark:
78 |
79 | while j < len(loudn_freq) and bsi > loudn_freq[j]:
80 | j += 1
81 |
82 | j -= 1
83 |
84 | if np.where(loudn_freq == bsi)[0].size != 0: # loudness value for this frequency already exists
85 | loudn_bark[:,i] = eq_loudness[:,np.where(loudn_freq == bsi)][:,0,0]
86 | else:
87 | w1 = 1 / np.abs(loudn_freq[j] - bsi)
88 | w2 = 1 / np.abs(loudn_freq[j + 1] - bsi)
89 | loudn_bark[:,i] = (eq_loudness[:,j]*w1 + eq_loudness[:,j+1]*w2) / (w1 + w2)
90 |
91 | i += 1
92 |
93 |
94 |
95 | # SPECTRAL MASKING Spreading Function
96 | # CONST_spread contains matrix of spectral frequency masking factors
97 |
98 | CONST_spread = np.zeros((n_bark_bands,n_bark_bands))
99 |
100 | for i in range(n_bark_bands):
101 | CONST_spread[i,:] = 10**((15.81+7.5*((i-np.arange(n_bark_bands))+0.474)-17.5*(1+((i-np.arange(n_bark_bands))+0.474)**2)**0.5)/10)
102 |
103 |
104 |
105 | # UTILITY FUNCTIONS
106 |
107 |
108 | def nextpow2(num):
109 | '''NextPow2
110 |
111 | find the next highest number to the power of 2 to a given number
112 | and return the exponent to 2
113 | (analogously to Matlab's nextpow2() function)
114 | '''
115 |
116 | n = 2
117 | i = 1
118 | while n < num:
119 | n *= 2
120 | i += 1
121 | return i
122 |
123 |
124 |
125 | # FFT FUNCTIONS
126 |
127 | def periodogram(x,win,Fs=None,nfft=1024):
128 | ''' Periodogram
129 |
130 | Periodogram power spectral density estimate
131 | Note: this function was written with 1:1 Matlab compatibility in mind.
132 |
133 | The number of points, nfft, in the discrete Fourier transform (DFT) is the maximum of 256 or the next power of two greater than the signal length.
134 |
135 | :param x: time series data (e.g. audio signal), ideally length matches nfft
136 | :param win: window function to be applied (e.g. Hanning window). in this case win expects already data points of the window to be provided.
137 | :param Fs: sampling frequency (unused)
138 | :param nfft: number of bins for FFT (ideally matches length of x)
139 | :return: Periodogram power spectrum (np.array)
140 | '''
141 |
142 |
143 | #if Fs == None:
144 | # Fs = 2 * np.pi # commented out because unused
145 |
146 | U = np.dot(win.conj().transpose(), win) # compensates for the power of the window.
147 | Xx = fft((x * win),nfft) # verified
148 | P = Xx*np.conjugate(Xx)/U
149 |
150 | # Compute the 1-sided or 2-sided PSD [Power/freq] or mean-square [Power].
151 | # Also, compute the corresponding freq vector & freq units.
152 |
153 | # Generate the one-sided spectrum [Power] if so wanted
154 | if nfft % 2 != 0:
155 | select = np.arange((nfft+1)/2) # ODD
156 | P = P[select,:] # Take only [0,pi] or [0,pi)
157 | P[1:-1] = P[1:-1] * 2 # Only DC is a unique point and doesn't get doubled
158 | else:
159 | #select = np.arange(nfft/2+1); # EVEN
160 | #P = P[select,:] # Take only [0,pi] or [0,pi) # TODO: why commented out?
161 | P[1:-2] = P[1:-2] * 2
162 |
163 | P = P / (2 * np.pi)
164 |
165 | return P
166 |
167 |
168 |
169 |
170 | def calc_spectrogram(wavsegment,fft_window_size,fft_overlap = 0.5,real_values=True):
171 |
172 | ''' Calc_Spectrogram
173 |
174 | calculate spectrogram using periodogram function (which performs FFT) to convert wave signal data
175 | from time to frequency domain (applying a Hanning window and (by default) 50 % window overlap)
176 |
177 | :param wavsegment: audio wave file data for a segment to be analyzed (mono (i.e. 1-dimensional vector) only
178 | :param fft_window_size: windows size to apply FFT to
179 | :param fft_overlap: overlap to apply during FFT analysis in % fraction (e.g. default = 0.5, means 50% overlap)
180 | :param real_values: if True, return real values by taking abs(spectrogram), if False return complex values
181 | :return: spectrogram matrix as numpy array (fft_window_size, n_frames)
182 | '''
183 |
184 | # hop_size (increment step in samples, determined by fft_window_size and fft_overlap)
185 | hop_size = int(fft_window_size*(1-fft_overlap))
186 |
187 | # this would compute the segment length, but it's pre-defined above ...
188 | # segment_size = fft_window_size + (frames-1) * hop_size
189 | # ... therefore we convert the formula to give the number of frames needed to iterate over the segment:
190 | n_frames = (wavsegment.shape[0] - fft_window_size) / hop_size + 1
191 | # n_frames_old = wavsegment.shape[0] / fft_window_size * 2 - 1 # number of iterations with 50% overlap
192 |
193 | # TODO: provide this as parameter for better caching?
194 | han_window = np.hanning(fft_window_size) # verified
195 |
196 | # initialize result matrix for spectrogram
197 | spectrogram = np.zeros((fft_window_size, n_frames), dtype=np.complex128)
198 |
199 | # start index for frame-wise iteration
200 | ix = 0
201 |
202 | for i in range(n_frames): # stepping through the wave segment, building spectrum for each window
203 | spectrogram[:,i] = periodogram(wavsegment[ix:ix+fft_window_size], win=han_window,nfft=fft_window_size)
204 | ix = ix + hop_size
205 |
206 | # NOTE: tested scipy periodogram BUT it delivers totally different values AND takes 2x the time of our periodogram function (0.13 sec vs. 0.06 sec)
207 | # from scipy.signal import periodogram # move on top
208 | #f, spec = periodogram(x=wavsegment[idx],fs=samplerate,window='hann',nfft=fft_window_size,scaling='spectrum',return_onesided=True)
209 |
210 | if real_values: spectrogram = np.abs(spectrogram)
211 |
212 | return (spectrogram)
213 |
214 |
215 | # FEATURE FUNCTIONS
216 |
217 | def calc_statistical_features(matrix):
218 |
219 | result = np.zeros((matrix.shape[0],7))
220 |
221 | result[:,0] = np.mean(matrix, axis=1)
222 | result[:,1] = np.var(matrix, axis=1, dtype=np.float64) # the values for variance differ between MATLAB and Numpy!
223 | result[:,2] = stats.skew(matrix, axis=1)
224 | result[:,3] = stats.kurtosis(matrix, axis=1, fisher=False) # Matlab calculates Pearson's Kurtosis
225 | result[:,4] = np.median(matrix, axis=1)
226 | result[:,5] = np.min(matrix, axis=1)
227 | result[:,6] = np.max(matrix, axis=1)
228 |
229 | result[np.where(np.isnan(result))] = 0
230 |
231 | return result
232 |
233 |
234 | # PSYCHO-ACOUSTIC TRANSFORMS as individual functions
235 |
236 |
237 | # Transform 2 Mel Scale: NOT USED by rp_extract, but included for testing purposes or for import into other programs
238 |
239 | def transform2mel(spectrogram,samplerate,fft_window_size,n_mel_bands = 80,freq_min = 0,freq_max = None):
240 | '''Transform to Mel
241 |
242 | convert a spectrogram to a Mel scale spectrogram by grouping original frequency bins
243 | to Mel frequency bands (using Mel filter from Librosa)
244 |
245 | Parameters
246 | spectrogram: input spectrogram
247 | samplerate: samplerate of audio signal
248 | fft_window_size: number of time window / frequency bins in the FFT analysis
249 | n_mel_bands: number of desired Mel bands, typically 20, 40, 80 (max. 128 which is default when 'None' is provided)
250 | freq_min: minimum frequency (Mel filters will be applied >= this frequency, but still return n_meld_bands number of bands)
251 | freq_max: cut-off frequency (Mel filters will be applied <= this frequency, but still return n_meld_bands number of bands)
252 |
253 | Returns:
254 | mel_spectrogram: Mel spectrogram: np.array of shape(n_mel_bands,frames) maintaining the number of frames in the original spectrogram
255 | '''
256 |
257 | from librosa.filters import mel
258 |
259 | # Syntax: librosa.filters.mel(sr, n_fft, n_mels=128, fmin=0.0, fmax=None, htk=False)
260 | mel_basis = mel(samplerate,fft_window_size, n_mels=n_mel_bands,fmin=freq_min,fmax=freq_max)
261 |
262 | freq_bin_max = mel_basis.shape[1] # will be fft_window_size / 2 + 1
263 |
264 | # IMPLEMENTATION WITH FOR LOOP
265 | # initialize Mel Spectrogram matrix
266 | #n_mel_bands = mel_basis.shape[0] # get the number of bands from result in case 'None' was specified as parameter
267 | #mel_spectrogram = np.empty((n_mel_bands, frames))
268 |
269 | #for i in range(frames): # stepping through the wave segment, building spectrum for each window
270 | # mel_spectrogram[:,i] = np.dot(mel_basis,spectrogram[0:freq_bin_max,i])
271 |
272 | # IMPLEMENTATION WITH DOT PRODUCT (15% faster)
273 | # multiply the mel filter of each band with the spectogram frame (dot product executes it on all frames)
274 | # filter will be adapted in a way so that frequencies beyond freq_max will be discarded
275 | mel_spectrogram = np.dot(mel_basis,spectrogram[0:freq_bin_max,:])
276 | return (mel_spectrogram)
277 |
278 |
279 |
280 |
281 | # Bark Transform: Convert Spectrogram to Bark Scale
282 | # matrix: Spectrogram values as returned from periodogram function
283 | # freq_axis: array of frequency values along the frequency axis
284 | # max_bands: limit number of Bark bands (1...24) (counting from lowest band)
285 | def transform2bark(matrix, freq_axis, max_bands=None):
286 |
287 | # barks and n_bark_bands have been initialized globally above
288 |
289 | if max_bands == None:
290 | max_band = n_bark_bands
291 | else:
292 | max_band = min(n_bark_bands,max_bands)
293 |
294 | matrix_out = np.zeros((max_band,matrix.shape[1]),dtype=matrix.dtype)
295 |
296 | for b in range(max_band-1):
297 | # TODO: VisibleDeprecationWarning: boolean index did not match indexed array along dimension 0; dimension is 1024 but corresponding boolean dimension is 513
298 | matrix_out[b] = np.sum(matrix[((freq_axis >= barks[b]) & (freq_axis < barks[b+1]))], axis=0)
299 |
300 | return(matrix_out)
301 |
302 | # Spectral Masking (assumes values are arranged in <=24 Bark bands)
303 | def do_spectral_masking(matrix):
304 |
305 | n_bands = matrix.shape[0]
306 |
307 | # CONST_spread has been initialized globally above
308 | spread = CONST_spread[0:n_bands,0:n_bands] # not sure if column limitation is right here; was originally written for n_bark_bands = 24 only
309 | matrix = np.dot(spread, matrix)
310 | return(matrix)
311 |
312 | # Map to Decibel Scale
313 | def transform2db(matrix):
314 | '''Map to Decibel Scale'''
315 | matrix[np.where(matrix < 1)] = 1
316 | matrix = 10 * np.log10(matrix)
317 | return(matrix)
318 |
319 | # Transform to Phon (assumes matrix is in dB scale)
320 | def transform2phon(matrix):
321 |
322 | old_npsetting = np.seterr(invalid='ignore') # avoid 'RuntimeWarning: invalid value encountered in divide' at ifac division below
323 |
324 | # number of bark bands, matrix length in time dim
325 | n_bands = matrix.shape[0]
326 | t = matrix.shape[1]
327 |
328 | # DB-TO-PHON BARK-SCALE-LIMIT TABLE
329 | # introducing 1 level more with level(1) being infinite
330 | # to avoid (levels - 1) producing errors like division by 0
331 |
332 | #%%table_dim = size(CONST_loudn_bark,2);
333 | table_dim = n_bands; # OK
334 | cbv = np.concatenate((np.tile(np.inf,(table_dim,1)), loudn_bark[:,0:n_bands].transpose()),1) # OK
335 |
336 | # init lowest level = 2
337 | levels = np.tile(2,(n_bands,t)) # OK
338 |
339 | for lev in range(1,6): # OK
340 | db_thislev = np.tile(np.asarray([cbv[:,lev]]).transpose(),(1,t))
341 | levels[np.where(matrix > db_thislev)] = lev + 2
342 |
343 | # the matrix 'levels' stores the correct Phon level for each data point
344 | cbv_ind_hi = np.ravel_multi_index(dims=(table_dim,7), multi_index=np.array([np.tile(np.array([range(0,table_dim)]).transpose(),(1,t)), levels-1]), order='F')
345 | cbv_ind_lo = np.ravel_multi_index(dims=(table_dim,7), multi_index=np.array([np.tile(np.array([range(0,table_dim)]).transpose(),(1,t)), levels-2]), order='F')
346 |
347 | # interpolation factor % OPT: pre-calc diff
348 | ifac = (matrix[:,0:t] - cbv.transpose().ravel()[cbv_ind_lo]) / (cbv.transpose().ravel()[cbv_ind_hi] - cbv.transpose().ravel()[cbv_ind_lo])
349 |
350 | ifac[np.where(levels==2)] = 1 # keeps the upper phon value;
351 | ifac[np.where(levels==8)] = 1 # keeps the upper phon value;
352 |
353 | # phons has been initialized globally above
354 |
355 | matrix[:,0:t] = phons.transpose().ravel()[levels - 2] + (ifac * (phons.transpose().ravel()[levels - 1] - phons.transpose().ravel()[levels - 2])) # OPT: pre-calc diff
356 |
357 | np.seterr(invalid=old_npsetting['invalid']) # restore RuntimeWarning setting for np division error
358 |
359 | return(matrix)
360 |
361 |
362 | # Transform to Sone scale (assumes matrix is in Phon scale)
363 | def transform2sone(matrix):
364 | idx = np.where(matrix >= 40)
365 | not_idx = np.where(matrix < 40)
366 |
367 | matrix[idx] = 2**((matrix[idx]-40)/10) #
368 | matrix[not_idx] = (matrix[not_idx]/40)**2.642 # max => 438.53
369 | return(matrix)
370 |
371 |
372 | # MAIN Rhythm Pattern Extraction Function
373 |
374 | def rp_extract( wavedata, # pcm (wav) signal data normalized to (-1,1)
375 | samplerate, # signal sampling rate
376 |
377 | # which features to extract
378 | extract_rp = False, # extract Rhythm Patterns features
379 | extract_ssd = False, # extract Statistical Spectrum Descriptor
380 | extract_tssd = False, # extract temporal Statistical Spectrum Descriptor
381 | extract_rh = False, # extract Rhythm Histogram features
382 | extract_rh2 = False, # extract Rhythm Histogram features including Fluctuation Strength Weighting
383 | extract_trh = False, # extract temporal Rhythm Histogram features
384 | extract_mvd = False, # extract modulation variance descriptor
385 |
386 | # processing options
387 | skip_leadin_fadeout = 1, # >=0 how many sample windows to skip at the beginning and the end
388 | step_width = 1, # >=1 each step_width'th sample window is analyzed
389 | n_bark_bands = 24, # 2..24 number of desired Bark bands (from low frequencies to high) (e.g. 15 or 20 or 24 for 11, 22 and 44 kHz audio respectively) (1 delivers undefined output)
390 | mod_ampl_limit = 60, # 2..257 number of modulation frequencies on x-axis
391 |
392 | # enable/disable parts of feature extraction
393 | transform_bark = True, # [S2] transform to Bark scale
394 | spectral_masking = True, # [S3] compute Spectral Masking
395 | transform_db = True, # [S4] transfrom to dB: advisable only to turn off when [S5] and [S6] are turned off too
396 | transform_phon = True, # [S5] transform to Phon: if disabled, Sone_transform will be disabled too
397 | transform_sone = True, # [S6] transform to Sone scale (only applies if transform_phon = True)
398 | fluctuation_strength_weighting = True, # [R2] apply Fluctuation Strength weighting curve
399 | #blurring = True # [R3] Gradient+Gauss filter # TODO: not yet implemented
400 |
401 | return_segment_features = False, # this will return features per each analyzed segment instead of aggregated ones
402 | verbose = True # print messages whats going on
403 | ):
404 |
405 | '''Rhythm Pattern Feature Extraction
406 |
407 | performs segment-wise audio feature extraction from provided audio wave (PCM) data
408 | and extracts the following features:
409 |
410 | Rhythm Pattern
411 | Statistical Spectrum Descriptor
412 | Statistical Histogram
413 | temporal Statistical Spectrum Descriptor
414 | Rhythm Histogram
415 | temporal Rhythm Histogram features
416 | Modulation Variance Descriptor
417 |
418 | Examples:
419 | >>> from audiofile_read import *
420 | >>> samplerate, samplewidth, wavedata = audiofile_read("music/BoxCat_Games_-_10_-_Epic_Song.mp3") #doctest: +ELLIPSIS
421 | Decoded .mp3 with: mpg123 -q -w /....wav music/BoxCat_Games_-_10_-_Epic_Song.mp3
422 | >>> feat = rp_extract(wavedata, samplerate, extract_rp=True, extract_ssd=True, extract_rh=True)
423 | Analyzing 7 segments
424 | >>> for k in feat.keys():
425 | ... print k.upper() + ":", feat[k].shape[0], "dimensions"
426 | SSD: 168 dimensions
427 | RH: 60 dimensions
428 | RP: 1440 dimensions
429 | >>> print feat["rp"]
430 | [ 0.01599218 0.01979605 0.01564305 0.01674175 0.00959912 0.00931604 0.00937831 0.00709122 0.00929631 0.00754473 ..., 0.02998088 0.03602739 0.03633861 0.03664331 0.02589753 0.02110256
431 | 0.01457744 0.01221825 0.0073788 0.00164668]
432 | >>> print feat["rh"]
433 | [ 7.11614842 12.58303013 6.96717295 5.24244146 6.49677561 4.21249659 12.43844045 4.19672357 5.30714983 6.1674115 ..., 1.55870044 2.69988854 2.75075831 3.67269877 13.0351257
434 | 11.7871738 3.76106713 2.45225195 2.20457928 2.06494926]
435 | >>> print feat["ssd"]
436 | [ 3.7783279 5.84444695 5.58439197 4.87849697 4.14983056 4.09638223 4.04971225 3.96152261 3.65551062 3.2857232 ..., 14.45953191 14.6088727 14.03351539 12.84783095 10.81735946
437 | 9.04121124 7.13804008 5.6633501 3.09678286 0.52076428]
438 |
439 | '''
440 |
441 |
442 | # PARAMETER INITIALIZATION
443 | # non-exhibited parameters
444 | include_DC = False
445 | FLATTEN_ORDER = 'F' # order how matrices are flattened to vector: 'F' for Matlab/Fortran, 'C' for C order (IMPORTANT TO USE THE SAME WHEN reading+reshaping the features)
446 |
447 | # segment_size should always be ~6 sec, fft_window_size should always be ~ 23ms
448 |
449 | if (samplerate == 11025):
450 | segment_size = 2**16
451 | fft_window_size = 256
452 | elif (samplerate == 22050):
453 | segment_size = 2**17
454 | fft_window_size = 512
455 | elif (samplerate == 44100):
456 | segment_size = 2**18
457 | fft_window_size = 1024
458 | else:
459 | # throw error not supported
460 | raise ValueError('A sample rate of ' + str(samplerate) + " is not supported (only 11, 22 and 44 kHz).")
461 |
462 | # calculate frequency values on y-axis (for Bark scale calculation):
463 | # freq_axis = float(samplerate)/fft_window_size * np.arange(0,(fft_window_size/2) + 1)
464 | # linear space from 0 to samplerate/2 in (fft_window_size/2+1) steps
465 | freq_axis = np.linspace(0, float(samplerate)/2, int(fft_window_size//2) + 1, endpoint=True)
466 |
467 |
468 | # CONVERT STEREO TO MONO: Average the channels
469 | if wavedata.ndim > 1: # if we have more than 1 dimension
470 | if wavedata.shape[1] == 1: # check if 2nd dimension is just 1
471 | wavedata = wavedata[:,0] # then we take first and only channel
472 | else:
473 | wavedata = np.mean(wavedata, 1) # otherwise we average the signals over the channels
474 |
475 |
476 | # SEGMENT INITIALIZATION
477 | # find positions of wave segments
478 |
479 | skip_seg = skip_leadin_fadeout
480 | seg_pos = np.array([1, segment_size]) # array with 2 entries: start and end position of selected segment
481 |
482 | seg_pos_list = [] # list to store all the individual segment positions (only when return_segment_features == True)
483 |
484 | # if file is too small, don't skip leadin/fadeout and set step_width to 1
485 | if ((skip_leadin_fadeout > 0) or (step_width > 1)):
486 |
487 | duration = wavedata.shape[0]/samplerate
488 |
489 | if (duration < 45):
490 | step_width = 1
491 | skip_seg = 0
492 | # TODO: do this as a warning?
493 | if verbose: print "Duration < 45 seconds: setting step_width to 1 and skip_leadin_fadeout to 0."
494 |
495 | else:
496 | # advance by number of skip_seg segments (i.e. skip lead_in)
497 | seg_pos = seg_pos + segment_size * skip_seg
498 |
499 | # calculate number of segments
500 | n_segments = int(np.floor( (np.floor( (wavedata.shape[0] - (skip_seg*2*segment_size)) / segment_size ) - 1 ) / step_width ) + 1)
501 | if verbose: print "Analyzing", n_segments, "segments"
502 |
503 | if n_segments == 0:
504 | raise ValueError("Not enough data to analyze! Minimum sample length needs to be " +
505 | str(segment_size) + " (5.94 seconds) but it is " + str(wavedata.shape[0]) +
506 | " (" + str(round(wavedata.shape[0] * 1.0 / samplerate,2)) + " seconds)")
507 |
508 | # initialize output
509 | features = {}
510 |
511 | ssd_list = []
512 | sh_list = []
513 | rh_list = []
514 | rh2_list = []
515 | rp_list = []
516 | mvd_list = []
517 |
518 | hearing_threshold_factor = 0.0875 * (2**15)
519 |
520 | # SEGMENT ITERATION
521 |
522 | for seg_id in range(n_segments):
523 |
524 | # keep track of segment position
525 | if return_segment_features:
526 | seg_pos_list.append(seg_pos)
527 |
528 | # EXTRACT WAVE SEGMENT that will be processed
529 | # data is assumed to be mono waveform
530 | wavsegment = wavedata[seg_pos[0]-1:seg_pos[1]] # verified
531 |
532 | # v210715
533 | # Python : [-0.0269165 -0.02128601 -0.01864624 -0.01893616 -0.02166748 -0.02694702 -0.03457642 -0.04333496 -0.05166626 -0.05891418]
534 | # Matlab : [-0,0269165 -0,02125549 -0,01861572 -0,01893616 -0,02165222 -0,02694702 -0,03456115 -0,04331970 -0,05166626 -0,05891418]
535 |
536 |
537 | # adjust hearing threshold # TODO: move after stereo-mono conversion above?
538 | wavsegment = wavsegment * hearing_threshold_factor
539 |
540 | # v210715
541 | # Python : [ -77.175 -61.03125 -53.4625 -54.29375 -62.125 -77.2625 -99.1375 -124.25 -148.1375 -168.91875]
542 | # Matlab : [ -77,175 -60,94375 -53,3750 -54,29375 -62,081 -77,2625 -99,0938 -124,21 -148,1375 -168,91875]
543 |
544 | matrix = calc_spectrogram(wavsegment,fft_window_size)
545 |
546 | # v210715
547 | #Python: 0.01372537 0.51454915 72.96077581 84.86663379 2.09940049 3.29631279 97373.2756834 23228.2065494 2678.44451741 30467.235416
548 | # : 84.50635406 58.32826049 1263.82538188 234.11858349 85.48176796 97.26094525 214067.91208223 3570917.53366476 2303291.96676741 1681002.94519665
549 | # : 171.47168402 1498.04129116 3746.45491915 153.01444364 37.20801758 177.74229702 238810.1975412 3064388.50572536 5501187.79635479 4172009.81345923
550 |
551 | #Matlab: 0,01528259 0,49653179 73,32978523 85,38774541 2,00416767 3,36618763 97416,24267209 23239,84650814 2677,01521862 30460,9231041364
552 | # : 84,73805309 57,84524803 1263,40594029 235,62185973 85,13826606 97,61122652 214078,02415144 3571346,74831746 2303286,74666381 1680967,41922679
553 | # : 170,15377915 1500,98052242 3744,98456435 154,14108817 36,69362260 177,48982263 238812,02171250 3064642,99278220 5501230,26588318 4172058,72803277
554 | #
555 |
556 | # PSYCHO-ACOUSTIC TRANSFORMS
557 |
558 | # Map to Bark Scale
559 | if transform_bark:
560 | matrix = transform2bark(matrix,freq_axis,n_bark_bands)
561 |
562 | # v210715
563 | # Python: 255.991763 1556.884100 5083.2410768 471.9996609 124.789186 278.299555 550251.385306 6658534.245939 7807158.207639 5883479.99407189
564 | # : 77128.354925 10446.109041 22613.8525735 13266.2502432 2593.395039 1367.697057 675114.554043 23401741.536499 6300109.471193 8039710.71759598
565 | # : 127165.795400 91270.354107 15240.3501050 16291.2234730 1413.851495 2166.723800 868138.817452 20682384.237884 8971171.605009 5919089.97818692
566 |
567 | # Matlab: 254,907114 1559,322302 5081,720289 475,1506933 123,836056 278,46723 550306,288536 6659229,587607 7807194,027765 5883487,07036370
568 | # : 77118,196343 10447,961479 22605,559124 13266,4432995 2591,064037 1368,48462 675116,996782 23400723,570438 6300124,132022 8039688,83884099
569 | # : 127172,560642 91251,040768 15246,639683 16286,4542687 1414,053166 2166,42874 868063,055613 20681863,052695 8971108,607811 5919136,16752791
570 |
571 |
572 | # Spectral Masking
573 | if spectral_masking:
574 | matrix = do_spectral_masking(matrix)
575 |
576 | # v210715
577 | # Python: 12978.051641 3416.109125 8769.913963 2648.888265 547.12360 503.50224 660888.17361 10480839.33617 8840234.405272 7193404.23970964
578 | # : 100713.471006 27602.656332 27169.741240 16288.350176 2887.60281 1842.05959 1021358.42618 29229962.41626 10653981.441005 11182818.62910279
579 | # : 426733.607945 262537.326945 43522.106075 41091.381283 4254.39289 4617.45877 1315036.85377 31353824.35688 12417010.121754 9673923.23590653
580 |
581 | # Matlab: 12975,335615 3418,81282 8767,062187 2652,061105 545,79379 503,79683 660943,32199 10481368,76411 8840272,477464 7193407,85259461
582 | # : 100704,175421 27602,34142 27161,901160 16288,924458 2884,94883 1842,86020 1021368,99046 29229118,99738 10653999,341989 11182806,7524195
583 | # : 426751,992198 262523,89306 43524,970883 41085,415594 4253,42029 4617,35691 1314966,73269 31353021,99155 12416968,806879 9673951,88376021
584 |
585 |
586 | # Map to Decibel Scale
587 | if transform_db:
588 | matrix = transform2db(matrix)
589 |
590 | # v210715
591 | # Python: 41.13209498 35.33531736 39.42995333 34.23063639 27.38085455 27.02001413 58.2012798 70.20396064 69.46463781 68.56934467
592 | # : 50.03087564 44.40950878 44.34085502 42.11877097 34.60537456 32.65303677 60.09178176 74.65828257 70.27511936 70.48551281
593 | # : 56.30156848 54.19191059 46.38709903 46.1375074 36.28837595 36.64403027 61.18937924 74.96290521 70.94017035 69.85602637
594 |
595 | # Matlab: 41,13118599 35,33875324 39,42854087 34,23583526 27,37028596 27,02255437 58,20164218 70,20418000 69,46465651 68,56934684
596 | # : 50,03047477 44,40945923 44,33960164 42,11892409 34,60138115 32,65492392 60,09182668 74,65815725 70,27512665 70,48550820
597 | # : 56,30175557 54,19168835 46,38738489 46,13687684 36,28738298 36,64393446 61,18914765 74,96279407 70,94015590 69,85603922
598 |
599 |
600 | # Transform Phon
601 | if transform_phon:
602 | matrix = transform2phon(matrix)
603 |
604 | # v210715
605 | # Python: 25.90299283 17.82310731 23.4713619 16.37852452 7.42111749 6.94924924 47.58029453 60.22662293 59.43646085 58.49404702
606 | # : 47.03087564 41.40950878 41.34085502 38.89846372 29.5067182 27.06629597 57.09178176 71.65828257 67.27511936 67.48551281
607 | # : 55.02273887 52.91308099 45.10826943 44.8586778 34.3678058 34.769195 59.91054964 73.68407561 69.66134075 68.57719676
608 |
609 | # Matlab: 25,90169428 17,82760039 23,46934410 16,38532303 7,40729702 6,95257110 47,58067598 60,22686667 59,43648053 58,49404931
610 | # : 47,03047477 41,40945923 41,33960164 38,89865511 29,50172644 27,06865491 57,09182668 71,65815725 67,27512665 67,48550820
611 | # : 55,02292596 52,91285875 45,10855528 44,85804723 34,36668514 34,76908687 59,91031805 73,68396446 69,66132629 68,57720962
612 |
613 |
614 | # Transform Sone
615 | if transform_sone:
616 | matrix = transform2sone(matrix)
617 |
618 | # v210715
619 | # Python: 0.31726931 0.11815598 0.24452297 0.09450863 0.01167179 0.009812 1.6911791 4.06332931 3.84676603 3.60351463
620 | # : 1.62798518 1.10263162 1.09739697 0.92887876 0.44759842 0.35631529 3.26974511 8.97447943 6.62312431 6.72041945
621 | # : 2.83288863 2.44749871 1.42486669 1.40042797 0.669685 0.69054778 3.97527582 10.327417 7.81439442 7.24868691
622 |
623 | # Matlab: 0,31722728 0,11823469 0,24446743 0,09461230 0,01161444 0,00982439 1,69122381 4,06339796 3,84677128 3,60351520
624 | # : 1,62793994 1,10262783 1,09730163 0,92889083 0,44739839 0,35639734 3,26975529 8,97440147 6,62312765 6,72041730
625 | # : 2,83292537 2,44746100 1,42489491 1,40036676 0,66962731 0,69054210 3,97521200 10,32733744 7,81438659 7,24869337
626 |
627 |
628 | # FEATURES: now we got a Sonogram and extract statistical features
629 |
630 | # SSD: Statistical Spectrum Descriptors
631 | if (extract_ssd or extract_tssd):
632 | ssd = calc_statistical_features(matrix)
633 | ssd_list.append(ssd.flatten(FLATTEN_ORDER))
634 |
635 | # v210715
636 | # Python: 2.97307486 5.10356599 0.65305978 2.35489911 2.439558 0.009812 8.1447095
637 | # : 4.72262845 7.30899976 0.17862996 2.10446264 4.58595337 0.25538117 12.83339251
638 | # : 4.77858109 5.52646859 0.23911764 2.9056742 4.96338019 0.589568 13.6683906
639 | # : 4.43503421 3.69422906 0.41473155 3.06743402 4.33220988 0.88354694 10.89393754
640 | # : 3.77216546 2.3993334 0.84001713 4.35548197 3.65140589 1.01199696 11.07806891
641 | # : 3.60563073 2.09907968 1.49906811 7.07183968 3.35596471 1.00619842 11.2872743
642 | # : 3.56816128 2.20237398 1.69790808 7.57870223 3.33806767 1.10826324 10.84965392
643 | # : 3.43734647 2.38648202 1.59655791 6.86704341 3.23361995 1.10198021 11.89470587
644 | # : 3.18466303 2.39479532 1.99223131 8.83987184 2.8819031 0.93982524 11.28737448
645 | # : 2.90996406 1.85412568 1.97247446 8.36738395 2.68063918 0.81760102 9.64247378
646 |
647 | # Matlab: 2,97309758 5,11366933 0,65306558 2,35489605 2,43956735 0,00982439 8,14473582
648 | # : 4,72264163 7,32338449 0,17863061 2,10444843 4,58593777 0,25568703 12,83335168
649 | # : 4,77859306 5,53731457 0,23911126 2,90567055 4,96338616 0,58959588 13,66839858
650 | # : 4,43505068 3,70148292 0,41473410 3,06742263 4,33222037 0,88357883 10,89397920
651 | # : 3,77217541 2,40405654 0,84000183 4,35540491 3,65136495 1,01191651 11,07802201
652 | # : 3,60563459 2,10319516 1,49905911 7,07181623 3,35609824 1,00628652 11,28728291
653 | # : 3,56820841 2,20675908 1,69792784 7,57880557 3,33819690 1,10830805 10,84975850
654 | # : 3,43736757 2,39117736 1,59656951 6,86710630 3,23366165 1,10199096 11,89486723
655 | # : 3,18467212 2,39951286 1,99223621 8,83991021 2,88200015 0,93978494 11,28733449
656 | # : 2,90997546 1,85776617 1,97246361 8,36742039 2,68074853 0,81790606 9,64262886
657 |
658 | # values verified
659 |
660 | # RP: RHYTHM PATTERNS
661 | feature_part_xaxis1 = range(0,mod_ampl_limit) # take first (opts.mod_ampl_limit) values of fft result including DC component
662 | feature_part_xaxis2 = range(1,mod_ampl_limit+1) # leave DC component and take next (opts.mod_ampl_limit) values of fft result
663 |
664 | if (include_DC):
665 | feature_part_xaxis_rp = feature_part_xaxis1
666 | else:
667 | feature_part_xaxis_rp = feature_part_xaxis2
668 |
669 | # 2nd FFT
670 | fft_size = 2**(nextpow2(matrix.shape[1]))
671 |
672 | if (mod_ampl_limit >= fft_size):
673 | raise(ValueError("mod_ampl_limit option must be smaller than FFT window size (" + str(fft_size) + ")."))
674 | # NOTE: in fact only half of it (256) makes sense due to the symmetry of the FFT result
675 |
676 | rhythm_patterns = np.zeros((matrix.shape[0], fft_size), dtype=np.complex128)
677 | #rhythm_patterns = np.zeros((matrix.shape[0], fft_size), dtype=np.float64)
678 |
679 | # real_matrix = abs(matrix)
680 |
681 | for b in range(0,matrix.shape[0]):
682 |
683 | rhythm_patterns[b,:] = fft(matrix[b,:], fft_size)
684 |
685 | # tried this instead, but ...
686 | #rhythm_patterns[b,:] = fft(real_matrix[b,:], fft_size) # ... no performance improvement
687 | #rhythm_patterns[b,:] = rfft(real_matrix[b,:], fft_size) # ... different output values
688 |
689 | rhythm_patterns = rhythm_patterns / 256 # why 256?
690 |
691 | # convert from complex128 to float64 (real)
692 | rp = np.abs(rhythm_patterns[:,feature_part_xaxis_rp]) # verified
693 |
694 | # MVD: Modulation Variance Descriptors
695 | if extract_mvd:
696 | mvd = calc_statistical_features(rp.transpose()) # verified
697 | mvd_list.append(mvd.flatten(FLATTEN_ORDER))
698 |
699 | # RH: Rhythm Histograms - OPTION 1: before fluctuation_strength_weighting (as in Matlab)
700 | if extract_rh:
701 | rh = np.sum(np.abs(rhythm_patterns[:,feature_part_xaxis2]),axis=0) #without DC component # verified
702 | rh_list.append(rh.flatten(FLATTEN_ORDER))
703 |
704 | # final steps for RP:
705 |
706 | # Fluctuation Strength weighting curve
707 | if fluctuation_strength_weighting:
708 |
709 | # modulation frequency x-axis (after 2nd FFT)
710 | # mod_freq_res = resolution of modulation frequency axis (0.17 Hz)
711 | mod_freq_res = 1 / (float(segment_size) / samplerate)
712 |
713 | # modulation frequencies along x-axis from index 0 to 256)
714 | mod_freq_axis = mod_freq_res * np.array(feature_part_xaxis_rp)
715 |
716 | # fluctuation strength curve
717 | fluct_curve = 1 / (mod_freq_axis/4 + 4/mod_freq_axis)
718 |
719 | for b in range(rp.shape[0]):
720 | rp[b,:] = rp[b,:] * fluct_curve #[feature_part_xaxis_rp]
721 |
722 | #values verified
723 |
724 |
725 | # RH: Rhythm Histograms - OPTION 2 (after Fluctuation weighting)
726 | if extract_rh2:
727 | rh2 = np.sum(rp,axis=0) #TODO: adapt to do always without DC component
728 | rh2_list.append(rh2.flatten(FLATTEN_ORDER))
729 |
730 |
731 | # Gradient+Gauss filter
732 | #if extract_rp:
733 | # TODO Gradient+Gauss filter
734 |
735 | #for i in range(1,rp.shape[1]):
736 | # rp[:,i-1] = np.abs(rp[:,i] - rp[:,i-1]);
737 | #
738 | #rp = blur1 * rp * blur2;
739 |
740 | rp_list.append(rp.flatten(FLATTEN_ORDER))
741 |
742 | seg_pos = seg_pos + segment_size * step_width
743 |
744 |
745 | if extract_rp:
746 | if return_segment_features:
747 | features["rp"] = np.array(rp_list)
748 | else:
749 | features["rp"] = np.median(np.asarray(rp_list), axis=0)
750 |
751 | if extract_ssd:
752 | if return_segment_features:
753 | features["ssd"] = np.array(ssd_list)
754 | else:
755 | features["ssd"] = np.mean(np.asarray(ssd_list), axis=0)
756 |
757 | if extract_rh:
758 | if return_segment_features:
759 | features["rh"] = np.array(rh_list)
760 | else:
761 | features["rh"] = np.median(np.asarray(rh_list), axis=0)
762 |
763 | if extract_mvd:
764 | if return_segment_features:
765 | features["mvd"] = np.array(mvd_list)
766 | else:
767 | features["mvd"] = np.mean(np.asarray(mvd_list), axis=0)
768 |
769 | # NOTE: no return_segment_features for temporal features as they measure variation of features over time
770 |
771 | if extract_tssd:
772 | features["tssd"] = calc_statistical_features(np.asarray(ssd_list).transpose()).flatten(FLATTEN_ORDER)
773 |
774 | if extract_trh:
775 | features["trh"] = calc_statistical_features(np.asarray(rh_list).transpose()).flatten(FLATTEN_ORDER)
776 |
777 | if return_segment_features:
778 | # also include the segment positions in the result
779 | features["segpos"] = np.array(seg_pos_list)
780 | features["timepos"] = features["segpos"] / (samplerate * 1.0)
781 |
782 | return features
783 |
784 |
785 |
786 | # function to self test rp_extract if working properly
787 | def self_test():
788 | import doctest
789 | #doctest.testmod()
790 | doctest.run_docstring_examples(rp_extract, globals(), verbose=True)
791 |
792 |
793 |
794 | if __name__ == '__main__':
795 |
796 | import sys
797 | from audiofile_read import * # import our library for reading wav and mp3 files
798 |
799 | # process file given on command line or default song (included)
800 | if len(sys.argv) > 1:
801 | if sys.argv[1] == '-test': # RUN DOCSTRING SELF TEST
802 | print "Doing self test. If nothing is printed, it is ok."
803 | import doctest
804 | doctest.run_docstring_examples(rp_extract, globals()) #, verbose=True)
805 | exit() # Note: no output means that everything went fine
806 | else:
807 | audiofile = sys.argv[1]
808 | else:
809 | audiofile = "music/BoxCat_Games_-_10_-_Epic_Song.mp3"
810 |
811 | # Read audio file and extract features
812 | try:
813 |
814 | samplerate, samplewidth, wavedata = audiofile_read(audiofile)
815 |
816 | np.set_printoptions(suppress=True)
817 |
818 | bark_bands = 24 # choose the number of Bark bands (2..24)
819 | mod_ampl_limit = 60 # number modulation frequencies on x-axis
820 |
821 | feat = rp_extract(wavedata,
822 | samplerate,
823 | extract_rp=True,
824 | extract_ssd=True,
825 | extract_tssd=False,
826 | extract_rh=True,
827 | n_bark_bands=bark_bands,
828 | spectral_masking=True,
829 | transform_db=True,
830 | transform_phon=True,
831 | transform_sone=True,
832 | fluctuation_strength_weighting=True,
833 | skip_leadin_fadeout=1,
834 | step_width=1,
835 | mod_ampl_limit=mod_ampl_limit)
836 |
837 | # feat is a dict containing arrays for different feature sets
838 | print "Successfully extracted features:" , feat.keys()
839 |
840 | except ValueError, e:
841 | print e
842 | exit()
843 |
844 |
845 | print "Rhythm Histogram feature vector:"
846 | print feat["rh"]
847 |
848 | # EXAMPLE on how to plot the features
849 | do_plots = False
850 |
851 | if do_plots:
852 | from rp_plot import *
853 |
854 | plotrp(feat["rp"],rows=bark_bands,cols=mod_ampl_limit)
855 | plotrh(feat["rh"])
856 | plotssd(feat["ssd"],rows=bark_bands)
857 |
858 | # EXAMPLE on how to store RP features in CSV file
859 | # import pandas as pd
860 | # filename = "features.rp.csv"
861 | # rp = pd.DataFrame(feat["rp"].reshape([1,feat["rp"].shape[0]]))
862 | # rp.to_csv(filename)
--------------------------------------------------------------------------------
/wavio.py:
--------------------------------------------------------------------------------
1 | # wavio.py
2 | # Author: Warren Weckesser
3 | # License: BSD 3-Clause (http://opensource.org/licenses/BSD-3-Clause)
4 |
5 | # TODO: As of 2016, wavio is now available in PiPy. We could remove this file and add it to requirements.txt However the syntax changed and adaptions need to be made
6 |
7 | import wave as _wave
8 | import numpy as _np
9 |
10 |
11 | __version__ = "0.0.1"
12 |
13 |
14 | def _wav2array(nchannels, sampwidth, data):
15 | """data must be the string containing the bytes from the wav file."""
16 | num_samples, remainder = divmod(len(data), sampwidth * nchannels)
17 | if remainder > 0:
18 | raise ValueError('The length of data is not a multiple of '
19 | 'sampwidth * num_channels.')
20 | if sampwidth > 4:
21 | raise ValueError("sampwidth must not be greater than 4.")
22 |
23 | if sampwidth == 3:
24 | a = _np.empty((num_samples, nchannels, 4), dtype=_np.uint8)
25 | raw_bytes = _np.fromstring(data, dtype=_np.uint8)
26 | a[:, :, :sampwidth] = raw_bytes.reshape(-1, nchannels, sampwidth)
27 | a[:, :, sampwidth:] = (a[:, :, sampwidth - 1:sampwidth] >> 7) * 255
28 | result = a.view('>> rate = 22050 # samples per second
103 | >>> T = 3 # sample duration (seconds)
104 | >>> f = 440.0 # sound frequency (Hz)
105 | >>> t = np.linspace(0, T, T*rate, endpoint=False)
106 | >>> x = (2**23 - 1) * np.sin(2 * np.pi * f * t)
107 | >>> writewav24("sine24.wav", rate, x)
108 |
109 | """
110 | a32 = _np.asarray(data, dtype=_np.int32)
111 | if a32.ndim == 1:
112 | # Convert to a 2D array with a single column.
113 | a32.shape = a32.shape + (1,)
114 | # By shifting first 0 bits, then 8, then 16, the resulting output
115 | # is 24 bit little-endian.
116 | a8 = (a32.reshape(a32.shape + (1,)) >> _np.array([0, 8, 16])) & 255
117 | wavdata = a8.astype(_np.uint8).tostring()
118 |
119 | w = _wave.open(filename, 'wb')
120 | w.setnchannels(a32.shape[1])
121 | w.setsampwidth(3)
122 | w.setframerate(rate)
123 | w.writeframes(wavdata)
124 | w.close()
125 |
--------------------------------------------------------------------------------