m@2: # -*- coding: utf-8 -*- m@2: """ m@2: Created on Fri Sep 1 19:11:52 2017 m@2: m@2: @author: mariapanteli m@2: """ m@2: m@2: import pytest m@2: Maria@35: import os m@2: import numpy as np Maria@35: import pandas as pd m@85: Maria@3: import scripts.load_features as load_features m@2: m@2: feat_loader = load_features.FeatureLoader(win2sec=8) m@2: m@43: TEST_METADATA_FILE = os.path.join(os.path.dirname(__file__), os.path.pardir, m@43: 'data', 'sample_dataset', 'metadata.csv') m@43: TEST_MELODIA_FILE = os.path.join(os.path.dirname(__file__), os.path.pardir, m@43: 'data', 'sample_dataset', 'Melodia', 'mel_1_2_1.csv') Maria@3: m@2: def test_get_music_idx_from_bounds(): m@6: bounds = np.array([['0', '10.5', 'm']]) Maria@3: sr = feat_loader.framessr2 Maria@3: music_bounds = feat_loader.get_music_idx_from_bounds(bounds, sr=sr) Maria@3: # upper bound minus half window size Maria@34: #half_win_sec = 4.0 # assume 8-second window Maria@34: win_sec = 8 Maria@34: music_bounds_true = np.arange(np.round(sr * (np.float(bounds[-1, 1]) - win_sec)), dtype=int) Maria@3: assert np.array_equal(music_bounds, music_bounds_true) Maria@3: Maria@3: Maria@3: def test_get_music_idx_from_bounds_short_segment(): Maria@3: # anything less than half window size is not processed Maria@34: bounds = np.array([['0', '7.9', 'm']]) m@6: sr = feat_loader.framessr2 Maria@3: music_bounds = feat_loader.get_music_idx_from_bounds(bounds, sr=sr) Maria@3: music_bounds_true = np.array([]) Maria@3: assert np.array_equal(music_bounds, music_bounds_true) Maria@3: Maria@3: m@6: def test_get_music_idx_from_bounds_single_frame(): Maria@34: bounds = np.array([['0', '8.1', 'm']]) Maria@34: sr = feat_loader.framessr2 m@6: music_bounds = feat_loader.get_music_idx_from_bounds(bounds, sr=sr) m@6: music_bounds_true = np.array([0]) m@6: assert np.array_equal(music_bounds, music_bounds_true) m@6: m@6: Maria@3: def test_get_music_idx_from_bounds_mix_segments(): m@2: bounds = np.array([['0', '10.5', 'm'], Maria@3: ['10.5', '3.0', 's'], Maria@3: ['13.5', '5.0', 'm']]) m@2: sr = feat_loader.framessr2 m@2: music_bounds = feat_loader.get_music_idx_from_bounds(bounds, sr=sr) Maria@34: #half_win_sec = 4.0 # assume 8-second window Maria@34: win_sec = 8.0 # assume 8-second window Maria@34: music_bounds_true = np.concatenate([np.arange(np.round(sr * (10.5 - win_sec)), dtype=int), Maria@34: np.arange(np.round(sr * 13.5), Maria@34: np.round(sr * (18.5 - win_sec)), dtype=int)]) m@2: assert np.array_equal(music_bounds, music_bounds_true) m@6: m@6: m@6: def test_get_music_idx_from_bounds_overlap_segments(): m@6: bounds = np.array([['0', '10.5', 'm'], m@6: ['9.5', '3.0', 's'], m@6: ['11.5', '5.0', 'm']]) m@6: sr = feat_loader.framessr2 m@6: music_bounds = feat_loader.get_music_idx_from_bounds(bounds, sr=sr) m@6: half_win_sec = 4.0 # assume 8-second window Maria@34: win_sec = 8.0 # assume 8-second window Maria@34: music_bounds_true = np.concatenate([np.arange(np.round(sr * (10.5 - win_sec)), dtype=int), Maria@34: np.arange(np.round(sr * 11.5), Maria@34: np.round(sr * (16.5 - win_sec)), dtype=int)]) m@6: assert np.array_equal(music_bounds, music_bounds_true) m@6: m@6: m@8: def test_average_local_frames(): m@8: frames = np.array([[0, 0.5, 1], [1, 1, 1]]) m@8: aveframes = feat_loader.average_local_frames(frames) m@8: aveframes_true = np.array([[0.5], [1]]) m@8: assert np.array_equal(aveframes, aveframes_true) m@8: m@8: m@8: def test_average_local_frames_multiple_frames(): m@8: frames1 = np.concatenate([np.repeat(0.5, feat_loader.hop2), np.repeat(0, feat_loader.win2)]) m@8: frames2 = np.concatenate([np.repeat(1.5, feat_loader.hop2), np.repeat(1, feat_loader.win2)]) m@8: frames = np.vstack([frames1, frames2]) m@8: aveframes = feat_loader.average_local_frames(frames) m@8: aveframes_true = np.array([[0.5, 0], [1.5, 1]]) m@8: # test only the second frame which contains values 0 or values 1 for all 8-second frame entries m@8: assert np.array_equal(aveframes[:, 1], aveframes_true[:, 1]) m@8: m@8: m@8: def test_average_local_frames_std(): m@8: frames1 = np.concatenate([np.repeat(0.5, feat_loader.hop2), np.repeat(0, feat_loader.win2)]) m@8: frames2 = np.concatenate([np.repeat(1.5, feat_loader.hop2), np.repeat(1, feat_loader.win2)]) m@8: frames = np.vstack([frames1, frames2]) m@8: aveframes = feat_loader.average_local_frames(frames, getstd=True) m@8: aveframes_true = np.array([[0.5, 0], [1.5, 1], [0.1, 0], [0.1, 0]]) m@8: # test only the second frame which contains values 0 or values 1 for all 8-second frame entries m@8: assert np.array_equal(aveframes[:, 1], aveframes_true[:, 1]) Maria@35: Maria@35: Maria@35: def test_get_op_from_melspec_n_frames(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: melspec = np.random.randn(40, dur_frames) # melspec with 40 melbands Maria@35: melspec = melspec - np.min(melspec) # melspec must be positive Maria@35: opmel = feat_loader.get_op_from_melspec(melspec) Maria@35: n_frames = opmel.shape[0] Maria@35: # expect 4 frames for windows not centered and .5 sec hop size Maria@35: # np.round((dur_sec - feat_loader.win2sec) * feat_loader.framessr2) Maria@35: assert n_frames == 4 Maria@35: Maria@35: Maria@35: def test_get_op_from_melspec_n_bins(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: melspec = np.random.randn(40, dur_frames) # melspec with 40 melbands Maria@35: melspec = melspec - np.min(melspec) # melspec must be positive Maria@35: opmel = feat_loader.get_op_from_melspec(melspec) Maria@35: n_bins = opmel.shape[1] Maria@35: assert n_bins == 40 * 200 Maria@35: Maria@35: Maria@35: def test_get_op_from_melspec_K_bands(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: melspec = np.random.randn(40, dur_frames) # melspec with 40 melbands Maria@35: melspec = melspec - np.min(melspec) # melspec must be positive Maria@35: K = 2 Maria@35: opmel = feat_loader.get_op_from_melspec(melspec, K=K) Maria@35: n_bins = opmel.shape[1] Maria@35: assert n_bins == K * 200 Maria@35: Maria@35: Maria@35: def test_get_mfcc_from_melspec_n_coef(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: melspec = np.random.randn(40, dur_frames) # melspec with 40 melbands Maria@35: melspec = melspec - np.min(melspec) # melspec must be positive Maria@35: mfcc = feat_loader.get_mfcc_from_melspec(melspec, deltamfcc=False, avelocalframes=False) Maria@35: assert mfcc.shape[1] == 20 Maria@35: Maria@35: Maria@35: def test_get_mfcc_from_melspec_n_coef_delta(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: melspec = np.random.randn(40, dur_frames) # melspec with 40 melbands Maria@35: melspec = melspec - np.min(melspec) # melspec must be positive Maria@35: mfcc = feat_loader.get_mfcc_from_melspec(melspec, deltamfcc=True, avelocalframes=False) Maria@35: assert mfcc.shape[1] == 40 Maria@35: Maria@35: Maria@35: def test_get_mfcc_from_melspec_n_frames(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: melspec = np.random.randn(40, dur_frames) # melspec with 40 melbands Maria@35: melspec = melspec - np.min(melspec) # melspec must be positive Maria@35: mfcc = feat_loader.get_mfcc_from_melspec(melspec, deltamfcc=False, avelocalframes=False) Maria@35: assert mfcc.shape[0] == dur_frames Maria@35: Maria@35: Maria@35: def test_get_mfcc_from_melspec_n_frames_win2(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: melspec = np.random.randn(40, dur_frames) # melspec with 40 melbands Maria@35: melspec = melspec - np.min(melspec) # melspec must be positive Maria@35: mfcc = feat_loader.get_mfcc_from_melspec(melspec, deltamfcc=False, avelocalframes=True) Maria@35: n_frames_true = np.round((dur_sec - feat_loader.win2sec) * feat_loader.framessr2) Maria@35: assert mfcc.shape[0] == n_frames_true Maria@35: Maria@35: Maria@35: def test_get_ave_chroma_align(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: chroma = np.random.randn(60, dur_frames) # chroma with 60 bins Maria@35: chroma = chroma - np.min(chroma) # chroma must be positive Maria@35: ave_chroma = feat_loader.get_ave_chroma(chroma, alignchroma=True, avelocalframes=False) Maria@35: # the maximum bin across time is the first bin (after alignment) Maria@35: assert np.argmax(np.sum(ave_chroma, axis=0)) == 0 Maria@35: Maria@35: Maria@35: def test_get_ave_chroma_n_frames(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: chroma = np.random.randn(60, dur_frames) # chroma with 60 bins Maria@35: chroma = chroma - np.min(chroma) # chroma must be positive Maria@35: ave_chroma = feat_loader.get_ave_chroma(chroma, avelocalframes=True, stdlocalframes=False) Maria@35: n_frames_true = np.round((dur_sec - feat_loader.win2sec) * feat_loader.framessr2) Maria@35: assert ave_chroma.shape[0] == n_frames_true Maria@35: Maria@35: Maria@35: def test_get_ave_chroma_n_bins(): Maria@35: dur_sec = 10.0 Maria@35: dur_frames = np.int(np.round(dur_sec * feat_loader.framessr)) Maria@35: np.random.seed(1) Maria@35: chroma = np.random.randn(60, dur_frames) # chroma with 60 bins Maria@35: chroma = chroma - np.min(chroma) # chroma must be positive Maria@35: ave_chroma = feat_loader.get_ave_chroma(chroma, avelocalframes=True, stdlocalframes=True) Maria@35: assert ave_chroma.shape[1] == 120 Maria@35: Maria@35: Maria@35: def test_get_pb_for_file_empty(): Maria@35: pbihist = feat_loader.get_pb_for_file('') Maria@35: assert np.array_equal(pbihist, []) Maria@35: Maria@35: Maria@35: def test_get_pb_for_file_n_bins(): m@43: pbihist = feat_loader.get_pb_for_file(TEST_MELODIA_FILE, nmfpb=False, scale=False) Maria@35: assert pbihist.shape[1] == 3600 Maria@35: Maria@35: Maria@35: def test_get_pb_for_file_align(): m@43: pbihist = feat_loader.get_pb_for_file(TEST_MELODIA_FILE, nmfpb=False, scale=False) Maria@35: pbihist = pbihist.get_values() Maria@35: assert np.sum(pbihist[:, :60].ravel()) > np.sum(pbihist[:, 60:120].ravel()) Maria@35: Maria@35: Maria@35: def test_get_pb_for_file_nmf(): m@43: pbihist = feat_loader.get_pb_for_file(TEST_MELODIA_FILE, nmfpb=True, scale=False) Maria@35: assert pbihist.shape[1] == 240 Maria@35: Maria@35: Maria@35: def test_get_features(): m@43: df = pd.read_csv(TEST_METADATA_FILE) Maria@35: df = df.iloc[:1, :] Maria@35: os.chdir('data/') m@43: data_list = feat_loader.get_features(df, precomp_melody=False) Maria@35: os.chdir('..') Maria@35: assert len(np.unique(data_list[-1])) == 1 Maria@35: Maria@35: Maria@35: def test_get_features_n_files(): m@43: df = pd.read_csv(TEST_METADATA_FILE) Maria@35: n_files = 3 Maria@35: df = df.iloc[:n_files, :] Maria@35: os.chdir('data/') m@43: data_list = feat_loader.get_features(df, precomp_melody=False) Maria@35: os.chdir('..') Maria@35: assert len(np.unique(data_list[-1])) == n_files Maria@35: Maria@35: Maria@35: def test_get_features_n_frames(): m@43: df = pd.read_csv(TEST_METADATA_FILE) Maria@35: df = df.iloc[:1, :] Maria@35: os.chdir('data/') m@43: data_list = feat_loader.get_features(df, precomp_melody=False) Maria@35: os.chdir('..') Maria@35: dur_sec = 11.5 # duration of first file in metadata.csv is > 11 seconds Maria@35: n_frames_true = np.round((dur_sec - feat_loader.win2sec) * feat_loader.framessr2) Maria@35: assert len(data_list[0]) == n_frames_true Maria@35: