updated spectral and peak tests
This commit is contained in:
@@ -40,7 +40,6 @@ class SpectralCentroidAnalysis(Analysis):
|
||||
self.create_analysis(
|
||||
self.create_spccntr_analysis,
|
||||
fft.analysis['frames'][:],
|
||||
fft.analysis.attrs['win_size'],
|
||||
self.AnalysedAudioFile.samplerate
|
||||
)
|
||||
self.spccntr_window_count = None
|
||||
@@ -55,11 +54,10 @@ class SpectralCentroidAnalysis(Analysis):
|
||||
return ({'frames': output, 'times': times}, {})
|
||||
|
||||
@staticmethod
|
||||
def create_spccntr_analysis(fft, length, samplerate, output_format="freq"):
|
||||
def create_spccntr_analysis(fft, samplerate, output_format="ind"):
|
||||
'''
|
||||
Calculate the spectral centroid of the fft frames.
|
||||
|
||||
length: the length of the window used to calculate the FFT.
|
||||
samplerate: the samplerate of the audio analysed.
|
||||
output_format = Choose either "freq" for output in Hz or "ind" for bin
|
||||
index output
|
||||
@@ -74,16 +72,15 @@ class SpectralCentroidAnalysis(Analysis):
|
||||
return y
|
||||
# Calculate the centre frequency of each rfft bin.
|
||||
if output_format == "freq":
|
||||
freqs = np.fft.rfftfreq(length, 1.0/samplerate)
|
||||
freqs = np.fft.rfftfreq((np.size(fft, axis=1)*2)-1, 1.0/samplerate)
|
||||
elif output_format == "ind":
|
||||
freqs = np.arange(np.size(fft, axis=1))
|
||||
else:
|
||||
raise ValueError("\'{0}\' is not a valid output "
|
||||
"format.".format(output_format))
|
||||
# Calculate the weighted mean
|
||||
y = np.sum(magnitudes*freqs, axis=1) / (np.sum(magnitudes, axis=1)+np.finfo(float).eps)
|
||||
y = np.sum(magnitudes*freqs, axis=1) / (np.sum(magnitudes, axis=1))
|
||||
|
||||
# Convert from index to Hz
|
||||
return y
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -41,8 +41,6 @@ class SpectralCrestFactorAnalysis(Analysis):
|
||||
self.create_analysis(
|
||||
self.create_spccf_analysis,
|
||||
fft.analysis['frames'][:],
|
||||
fft.analysis.attrs['win_size'],
|
||||
self.AnalysedAudioFile.samplerate
|
||||
)
|
||||
self.spccf_window_count = None
|
||||
|
||||
@@ -56,19 +54,14 @@ class SpectralCrestFactorAnalysis(Analysis):
|
||||
return ({'frames': output, 'times': times}, {})
|
||||
|
||||
@staticmethod
|
||||
def create_spccf_analysis(fft, length, samplerate, output_format="freq"):
|
||||
def create_spccf_analysis(fft):
|
||||
'''
|
||||
Calculate the spectral crest factor of the fft frames.
|
||||
|
||||
length: the length of the window used to calculate the FFT.
|
||||
samplerate: the samplerate of the audio analysed.
|
||||
output_format = Choose either "freq" for output in Hz or "ind" for bin
|
||||
index output
|
||||
'''
|
||||
# Get the positive magnitudes of each bin.
|
||||
magnitudes = np.abs(fft)
|
||||
# Get highest magnitude
|
||||
if not np.nonzero(magnitudes)[0].any():
|
||||
if not np.nonzero(magnitudes)[0].size:
|
||||
y = np.empty(magnitudes.shape[0])
|
||||
y.fill(np.nan)
|
||||
return y
|
||||
|
||||
@@ -42,8 +42,6 @@ class SpectralFlatnessAnalysis(Analysis):
|
||||
self.create_analysis(
|
||||
self.create_spcflatness_analysis,
|
||||
fft.analysis['frames'][:],
|
||||
fft.analysis.attrs['win_size'],
|
||||
self.AnalysedAudioFile.samplerate
|
||||
)
|
||||
self.spcflatness_window_count = None
|
||||
|
||||
@@ -57,18 +55,13 @@ class SpectralFlatnessAnalysis(Analysis):
|
||||
return ({'frames': output, 'times': times}, {})
|
||||
|
||||
@staticmethod
|
||||
def create_spcflatness_analysis(fft, length, samplerate, output_format="freq"):
|
||||
def create_spcflatness_analysis(fft):
|
||||
'''
|
||||
Calculate the spectral flatness of the fft frames.
|
||||
|
||||
length: the length of the window used to calculate the FFT.
|
||||
samplerate: the samplerate of the audio analysed.
|
||||
output_format = Choose either "freq" for output in Hz or "ind" for bin
|
||||
index output
|
||||
'''
|
||||
# Get the positive magnitudes of each bin.
|
||||
magnitudes = np.abs(fft)
|
||||
if not np.nonzero(magnitudes)[0].any():
|
||||
if not np.nonzero(magnitudes)[0].size:
|
||||
y = np.empty(magnitudes.shape[0])
|
||||
y.fill(np.nan)
|
||||
return y
|
||||
@@ -77,7 +70,7 @@ class SpectralFlatnessAnalysis(Analysis):
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings('ignore')
|
||||
# Calculate the geometric mean of magnitudes
|
||||
geo_mean = stats.gmean(magnitudes, axis=1)
|
||||
geo_mean = np.e**np.mean(np.log(magnitudes), axis=1)
|
||||
# Calculate the arithmetic mean of magnitudes
|
||||
arith_mean = np.mean(magnitudes, axis=1)
|
||||
spectral_flatness = geo_mean / arith_mean
|
||||
|
||||
@@ -40,8 +40,6 @@ class SpectralFluxAnalysis(Analysis):
|
||||
self.create_analysis(
|
||||
self.create_spcflux_analysis,
|
||||
fft.analysis['frames'][:],
|
||||
fft.analysis.attrs['win_size'],
|
||||
self.AnalysedAudioFile.samplerate
|
||||
)
|
||||
self.spcflux_window_count = None
|
||||
|
||||
@@ -55,7 +53,7 @@ class SpectralFluxAnalysis(Analysis):
|
||||
return ({'frames': output, 'times': times}, {})
|
||||
|
||||
@staticmethod
|
||||
def create_spcflux_analysis(fft, length, samplerate, output_format="freq"):
|
||||
def create_spcflux_analysis(fft, samplerate):
|
||||
'''
|
||||
Calculate the spectral flux of the fft frames.
|
||||
|
||||
@@ -67,7 +65,7 @@ class SpectralFluxAnalysis(Analysis):
|
||||
# Get the positive magnitudes of each bin.
|
||||
magnitudes = np.abs(fft)
|
||||
# Get highest magnitude
|
||||
if not np.nonzero(magnitudes)[0].any():
|
||||
if not np.nonzero(magnitudes)[0].size:
|
||||
y = np.empty(magnitudes.shape[0])
|
||||
y.fill(np.nan)
|
||||
return y
|
||||
@@ -76,7 +74,7 @@ class SpectralFluxAnalysis(Analysis):
|
||||
# magnitude.
|
||||
rolled_mags = np.roll(magnitudes, 1, axis=0)[1:]
|
||||
sum_of_squares = np.sum((magnitudes[1:]-rolled_mags)**2., axis=1)
|
||||
spectral_flux = np.sqrt(sum_of_squares) / (length/2)
|
||||
spectral_flux = np.sqrt(sum_of_squares) / (np.size(fft, axis=1)/2)
|
||||
|
||||
return spectral_flux
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ class SpectralSpreadAnalysis(Analysis):
|
||||
self.create_analysis(
|
||||
fft.analysis['frames'][:],
|
||||
spccntr.analysis['frames'][:],
|
||||
fft.analysis.attrs['win_size'],
|
||||
self.AnalysedAudioFile.samplerate
|
||||
)
|
||||
self.spccntr_window_count = None
|
||||
@@ -59,7 +58,7 @@ class SpectralSpreadAnalysis(Analysis):
|
||||
return ({'frames': output, 'times': times}, {})
|
||||
|
||||
@staticmethod
|
||||
def create_spcsprd_analysis(fft, spectral_centroid, length, samplerate, output_format = "freq"):
|
||||
def create_spcsprd_analysis(fft, spectral_centroid, samplerate, output_format = "ind"):
|
||||
'''
|
||||
Calculate the spectral spread of the fft frames.
|
||||
|
||||
@@ -79,17 +78,17 @@ class SpectralSpreadAnalysis(Analysis):
|
||||
if output_format == "ind":
|
||||
freqs = np.arange(np.size(fft, axis=1))
|
||||
elif output_format == "freq":
|
||||
freqs = np.fft.rfftfreq(length, 1.0/samplerate)
|
||||
freqs = np.fft.rfftfreq((np.size(fft, axis=1)*2)-1, 1.0/samplerate)
|
||||
else:
|
||||
raise ValueError("\'{0}\' is not a valid output "
|
||||
"format.".format(output_format))
|
||||
|
||||
spectral_centroid = np.vstack(spectral_centroid)
|
||||
|
||||
a = np.power(freqs-spectral_centroid, 2)
|
||||
mag_sqrd = np.power(magnitudes, 2)
|
||||
a = (freqs-spectral_centroid)**2
|
||||
mag_sqrd = magnitudes**2
|
||||
# Calculate the weighted mean
|
||||
y = np.sqrt(np.sum(a*mag_sqrd, axis=1) / (np.sum(mag_sqrd, axis=1)+np.finfo(float).eps))
|
||||
y = np.sqrt(np.sum(a*mag_sqrd, axis=1) / (np.sum(mag_sqrd, axis=1)))
|
||||
|
||||
return y
|
||||
|
||||
|
||||
+13
-13
@@ -1,24 +1,24 @@
|
||||
# Specify analysis parameters for root mean square analysis.
|
||||
rms = {
|
||||
"window_size": 70,
|
||||
"window_size": 120,
|
||||
"overlap": 2,
|
||||
}
|
||||
|
||||
# Specify analysis parameters for variance analysis.
|
||||
variance = {
|
||||
"window_size": 70,
|
||||
"window_size": 120,
|
||||
"overlap": 2
|
||||
}
|
||||
|
||||
# Specify analysis parameters for temporal kurtosis analysis.
|
||||
kurtosis = {
|
||||
"window_size": 70,
|
||||
"window_size": 120,
|
||||
"overlap": 2
|
||||
}
|
||||
|
||||
# Specify analysis parameters for temporal skewness analysis.
|
||||
skewness = {
|
||||
"window_size": 70,
|
||||
"window_size": 120,
|
||||
"overlap": 2
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ matcher_weightings = {
|
||||
"kurtosis": 1.,
|
||||
"skewness": 1.,
|
||||
"variance": 3.,
|
||||
"harm_ratio": 1.
|
||||
"harm_ratio": 3.
|
||||
}
|
||||
|
||||
# Specifies the method for averaging analysis frames to create a single value
|
||||
@@ -59,11 +59,11 @@ analysis_dict = {
|
||||
"f0": "log2_median",
|
||||
"rms": "mean",
|
||||
"zerox": "mean",
|
||||
"spccntr": "mean",
|
||||
"spcsprd": "mean",
|
||||
"spcflux": "mean",
|
||||
"spccf": "mean",
|
||||
"spcflatness": "mean",
|
||||
"spccntr": "median",
|
||||
"spcsprd": "median",
|
||||
"spcflux": "median",
|
||||
"spccf": "median",
|
||||
"spcflatness": "median",
|
||||
"peak": "mean",
|
||||
"centroid": "mean",
|
||||
"kurtosis": "mean",
|
||||
@@ -82,11 +82,11 @@ analysis = {
|
||||
matcher = {
|
||||
# Force the re-matching of analyses
|
||||
"rematch": True,
|
||||
"grain_size": 70,
|
||||
"grain_size": 120,
|
||||
"overlap": 2,
|
||||
# Defines the number of matches to keep for synthesis. Note that this must
|
||||
# also be specified in the synthesis config
|
||||
"match_quantity": 1,
|
||||
"match_quantity": 20,
|
||||
# Choose the algorithm used to perform matching. kdtree is recommended for
|
||||
# larger datasets.
|
||||
"method": 'kdtree'
|
||||
@@ -103,7 +103,7 @@ synthesizer = {
|
||||
"enforce_f0": True,
|
||||
# Specify the ratio limit that is the grain can be modified by.
|
||||
"enf_f0_ratio_limit": 10.,
|
||||
"grain_size": 70,
|
||||
"grain_size": 120,
|
||||
"overlap": 2,
|
||||
# Normalize output, avoid clipping of final output by scaling the final
|
||||
# frames.
|
||||
|
||||
@@ -365,11 +365,25 @@ class Matcher:
|
||||
length = entry.samps_to_ms(entry.frames)
|
||||
hop_size = grain_length / overlap
|
||||
grain_indexes[ind][0] = int(length / hop_size) - 1
|
||||
grain_indexes[:, 1] = np.cumsum(grain_indexes[:, 0])
|
||||
grain_indexes[:, 1] = np.cumsum(grain_indexes[:, 0]).astype(int)
|
||||
grain_indexes[:, 0] = grain_indexes[:, 1] - grain_indexes[:, 0]
|
||||
return grain_indexes
|
||||
|
||||
def kdtree_matcher(self, grain_size, overlap):
|
||||
invalid_inds = []
|
||||
for i, entry in enumerate(self.target_db.analysed_audio):
|
||||
entry.generate_grain_times(grain_size, overlap, save_times=True)
|
||||
if not entry.times.size:
|
||||
invalid_inds.append(i)
|
||||
for i in sorted(invalid_inds, reverse=True):
|
||||
del self.target_db.analysed_audio[i]
|
||||
invalid_inds = []
|
||||
for i, entry in enumerate(self.source_db.analysed_audio):
|
||||
entry.generate_grain_times(grain_size, overlap, save_times=True)
|
||||
if not entry.times.size:
|
||||
invalid_inds.append(i)
|
||||
for i in sorted(invalid_inds, reverse=True):
|
||||
del self.source_db.analysed_audio[i]
|
||||
# Count grains of the source database
|
||||
source_sample_indexes = self.count_grains(self.source_db, grain_size, overlap)
|
||||
try:
|
||||
@@ -385,6 +399,7 @@ class Matcher:
|
||||
else:
|
||||
weightings = {x: 1. for x in self.matcher_analyses}
|
||||
|
||||
|
||||
for tind, target_entry in enumerate(self.target_db.analysed_audio):
|
||||
# Check if match data already exists and use it rather than
|
||||
# regenerating if it does.
|
||||
@@ -395,7 +410,7 @@ class Matcher:
|
||||
continue
|
||||
|
||||
# Create an array of grain times for target sample
|
||||
target_times = target_entry.generate_grain_times(grain_size, overlap, save_times=True)
|
||||
target_times = target_entry.times
|
||||
x_size = target_times.shape[0]
|
||||
match_indexes = np.empty((x_size, self.match_quantity))
|
||||
match_vals = np.empty((x_size, self.match_quantity))
|
||||
@@ -420,7 +435,7 @@ class Matcher:
|
||||
for sind, source_entry in enumerate(self.source_db.analysed_audio):
|
||||
self.logger.info("K-d Tree Matching: {0} to {1}".format(source_entry.name, target_entry.name))
|
||||
# Create an array of grain times for source sample
|
||||
source_times = source_entry.generate_grain_times(grain_size, overlap, save_times=True)
|
||||
source_times = source_entry.times
|
||||
if not source_times.size:
|
||||
continue
|
||||
|
||||
@@ -804,7 +819,10 @@ class Synthesizer:
|
||||
match_sample.generate_grain_times(match_grain_size, match_overlap, save_times=True)
|
||||
|
||||
# TODO: Make proper fix for grain index offset of 1
|
||||
match_grain = match_sample[match_grain_ind-1]
|
||||
try:
|
||||
match_grain = match_sample[match_grain_ind-1]
|
||||
except:
|
||||
pdb.set_trace()
|
||||
|
||||
if self.enforce_rms_bool:
|
||||
# Get the target sample from the database
|
||||
|
||||
+100
-98
@@ -10,8 +10,40 @@ from fileops import pathops
|
||||
import pdb
|
||||
import os
|
||||
import config
|
||||
import math
|
||||
|
||||
|
||||
class NumericAssertions:
|
||||
"""
|
||||
This class is following the UnitTest naming conventions.
|
||||
It is meant to be used along with unittest.TestCase like so :
|
||||
class MyTest(unittest.TestCase, NumericAssertions):
|
||||
...
|
||||
It needs python >= 2.6
|
||||
"""
|
||||
|
||||
def assertIsNaN(self, value, msg=None):
|
||||
"""
|
||||
Fail if provided value is not NaN
|
||||
"""
|
||||
standardMsg = "%s is not NaN" % str(value)
|
||||
try:
|
||||
if not math.isnan(value):
|
||||
self.fail(self._formatMessage(msg, standardMsg))
|
||||
except:
|
||||
self.fail(self._formatMessage(msg, standardMsg))
|
||||
|
||||
def assertIsNotNaN(self, value, msg=None):
|
||||
"""
|
||||
Fail if provided value is NaN
|
||||
"""
|
||||
standardMsg = "Provided value is NaN"
|
||||
try:
|
||||
if math.isnan(value):
|
||||
self.fail(self._formatMessage(msg, standardMsg))
|
||||
except:
|
||||
pass
|
||||
|
||||
class globalTests(unittest.TestCase):
|
||||
|
||||
"""Includes functions that are accesible to all audiofile tests."""
|
||||
@@ -478,141 +510,111 @@ class PeakAnalysisTests(globalTests):
|
||||
"""Tests Peak analysis generation"""
|
||||
|
||||
def setUp(self):
|
||||
# TODO: Write this test...
|
||||
"""Create functions and variables before each test is run."""
|
||||
self.sr = 44100
|
||||
self.f = 440
|
||||
x = np.arange(88200)
|
||||
self.sine_wave = np.sin(2*np.pi*self.f/self.sr*x)
|
||||
self.silence = np.zeros(512)
|
||||
self.positive_max = np.ones(512)
|
||||
self.negative_max = np.ones(512)-2
|
||||
|
||||
def test_GeneratePeak(self):
|
||||
"""Check that RMS values generated are the expected values"""
|
||||
output = analysis.PeakAnalysis.create_peak_analysis(self.sine_wave)
|
||||
self.assertTrue(np.all(output > 0.8))
|
||||
output = analysis.PeakAnalysis.create_peak_analysis(self.silence)
|
||||
output1 = analysis.PeakAnalysis.create_peak_analysis(self.positive_max)
|
||||
output2 = analysis.PeakAnalysis.create_peak_analysis(self.negative_max)
|
||||
|
||||
class SpectralCentroidAnalysisTests(globalTests):
|
||||
np.testing.assert_array_equal(output, 0)
|
||||
np.testing.assert_array_equal(output1, 1)
|
||||
np.testing.assert_array_equal(output2, 1)
|
||||
|
||||
class SpectralCentroidAnalysisTests(globalTests, NumericAssertions):
|
||||
"""Tests Spectral Centroid analysis generation."""
|
||||
|
||||
def setUp(self):
|
||||
"""Create functions and variables before each test is run."""
|
||||
self.TestAudio = self.create_test_audio()
|
||||
# Specify frequency of the sine wave
|
||||
self.sr = 44100
|
||||
self.f = 440
|
||||
x = np.arange(88200)
|
||||
self.sine_wave = np.sin(2*np.pi*self.f/self.sr*x)
|
||||
self.silence = np.zeros(512)
|
||||
self.equal_mag = np.ones(512)
|
||||
self.peak = self.silence.copy()
|
||||
self.peak[256] = 1
|
||||
|
||||
def test_GenerateSpectralCentroid(self):
|
||||
fft = analysis.FFTAnalysis.stft(self.sine_wave, 512)
|
||||
output = analysis.SpectralCentroidAnalysis.create_spccntr_analysis(fft, 512, self.sr)
|
||||
average_output = np.median(output)
|
||||
self.assertTrue(self.f-2 <= average_output <= self.f+2)
|
||||
output = analysis.SpectralCentroidAnalysis.create_spccntr_analysis([self.silence], 44100)
|
||||
output1 = analysis.SpectralCentroidAnalysis.create_spccntr_analysis([self.peak], 44100)
|
||||
output2 = analysis.SpectralCentroidAnalysis.create_spccntr_analysis([self.equal_mag], 44100)
|
||||
self.assertIsNaN(output)
|
||||
self.assertEqual(output1, 256)
|
||||
self.assertEqual(output2, 255.5)
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Delete anything that is left over once tests are complete.
|
||||
|
||||
For example, remove all temporary test audio files generated during the
|
||||
tests.
|
||||
"""
|
||||
del self.TestAudio
|
||||
pathops.delete_if_exists("./.TestAudio.wav")
|
||||
|
||||
|
||||
class SpectralSpreadAnalysisTests(globalTests):
|
||||
class SpectralSpreadAnalysisTests(globalTests, NumericAssertions):
|
||||
"""Tests Spectral Spread analysis generation."""
|
||||
|
||||
def setUp(self):
|
||||
"""Create functions and variables before each test is run."""
|
||||
self.TestAudio = self.create_test_audio()
|
||||
# Specify frequency of the sine wave
|
||||
self.sr = 44100
|
||||
self.f = 440
|
||||
x = np.arange(88200)
|
||||
self.sine_wave = np.sin(2*np.pi*self.f/self.sr*x)
|
||||
self.white_noise = np.random.random(88200)
|
||||
self.silence = np.zeros(512)
|
||||
self.equal_mag = np.ones(512)
|
||||
self.peak = self.silence.copy()
|
||||
self.peak[256] = 1
|
||||
|
||||
def test_GenerateSpectralSpread(self):
|
||||
fft = analysis.FFTAnalysis.stft(self.sine_wave, 512)
|
||||
output = analysis.SpectralCentroidAnalysis.create_spccntr_analysis(fft, 512, self.sr, output_format = 'freq')
|
||||
average_output = np.median(output)
|
||||
output = analysis.SpectralSpreadAnalysis.create_spcsprd_analysis(fft, output, 512, self.sr, output_format='freq')
|
||||
output = output / (44100/2.0)
|
||||
average_output = np.median(output)
|
||||
|
||||
self.assertTrue(0 <= average_output <= 2)
|
||||
fft = analysis.FFTAnalysis.stft(self.white_noise, 512)
|
||||
output = analysis.SpectralCentroidAnalysis.create_spccntr_analysis(fft, 512, self.sr, output_format = 'ind')
|
||||
output = analysis.SpectralSpreadAnalysis.create_spcsprd_analysis(fft, output, 512, self.sr, output_format='freq')
|
||||
average_output = np.median(output)
|
||||
output = output / (44100/2.0)
|
||||
average_output = np.median(output)
|
||||
# self.assertTrue(8000 <= average_output)
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Delete anything that is left over once tests are complete.
|
||||
|
||||
For example, remove all temporary test audio files generated during the
|
||||
tests.
|
||||
"""
|
||||
del self.TestAudio
|
||||
pathops.delete_if_exists("./.TestAudio.wav")
|
||||
output = analysis.SpectralCentroidAnalysis.create_spccntr_analysis([self.silence], 44100)
|
||||
output = analysis.SpectralSpreadAnalysis.create_spcsprd_analysis([self.silence], output, 44100)
|
||||
output1 = analysis.SpectralCentroidAnalysis.create_spccntr_analysis([self.equal_mag], 44100)
|
||||
output1 = analysis.SpectralSpreadAnalysis.create_spcsprd_analysis([self.equal_mag], output1, 44100)
|
||||
output2 = analysis.SpectralCentroidAnalysis.create_spccntr_analysis([self.peak], 44100)
|
||||
output2 = analysis.SpectralSpreadAnalysis.create_spcsprd_analysis([self.peak], output2, 44100)
|
||||
self.assertIsNaN(output)
|
||||
np.testing.assert_almost_equal(output1, 147.801387)
|
||||
self.assertEquals(output2, 0)
|
||||
|
||||
class SpectralFluxAnalysisTests(globalTests):
|
||||
"""Tests Spectral Flux analysis generation."""
|
||||
|
||||
def setUp(self):
|
||||
# Specify frequency of the sine wave
|
||||
self.sr = 44100
|
||||
self.f = 440
|
||||
x = np.arange(44100)
|
||||
self.sine_wave = np.sin(2*np.pi*self.f/self.sr*x)
|
||||
self.white_noise = np.random.random(44100)
|
||||
self.input = np.concatenate((self.sine_wave, self.white_noise))
|
||||
self.silence = np.zeros(512)
|
||||
self.equal_mag = np.ones(512)
|
||||
self.peak = self.silence.copy()
|
||||
self.peak[256] = 1
|
||||
|
||||
def test_GenerateSpectralFlux(self):
|
||||
fft = analysis.FFTAnalysis.stft(self.input, 512)
|
||||
output = analysis.SpectralFluxAnalysis.create_spcflux_analysis(fft, 512, self.sr)
|
||||
x = np.vstack((self.equal_mag, self.peak))
|
||||
output = analysis.SpectralFluxAnalysis.create_spcflux_analysis(x, 512)
|
||||
x = np.vstack((self.peak, self.peak))
|
||||
output1 = analysis.SpectralFluxAnalysis.create_spcflux_analysis(x, 512)
|
||||
self.assertTrue(output[0] > output1[0])
|
||||
|
||||
output_max_index = np.argmax(output)
|
||||
self.assertTrue(output_max_index == output.size/2)
|
||||
|
||||
class SpectralCrestFactorAnalysisTests(globalTests):
|
||||
class SpectralCrestFactorAnalysisTests(globalTests, NumericAssertions):
|
||||
"""Tests Spectral Crest Factor analysis generation."""
|
||||
|
||||
def setUp(self):
|
||||
self.sr = 44100
|
||||
self.f = 440
|
||||
x = np.arange(44100)
|
||||
sine_wave = np.sin(2*np.pi*self.f/self.sr*x)
|
||||
white_noise = np.random.random(44100)
|
||||
silence = np.zeros(44100)
|
||||
self.input = np.concatenate((sine_wave, white_noise, silence))
|
||||
self.silence = np.zeros(512)
|
||||
self.equal_mag = np.ones(512)
|
||||
self.peak = self.silence.copy()
|
||||
self.peak[256] = 1
|
||||
|
||||
def test_GenerateSpectralCrestFactor(self):
|
||||
fft = analysis.FFTAnalysis.stft(self.input, 512)
|
||||
output = analysis.SpectralCrestFactorAnalysis.create_spccf_analysis(fft, 512, self.sr)
|
||||
# TODO: Write assertions for results. This isn't testing anything
|
||||
# otherwise...
|
||||
output = analysis.SpectralCrestFactorAnalysis.create_spccf_analysis([self.silence])
|
||||
output1 = analysis.SpectralCrestFactorAnalysis.create_spccf_analysis([self.equal_mag])
|
||||
output2 = analysis.SpectralCrestFactorAnalysis.create_spccf_analysis([self.peak])
|
||||
|
||||
class SpectralFlatnessAnalysisTests(globalTests):
|
||||
self.assertIsNaN(output)
|
||||
self.assertEquals(output1, 2./1024.)
|
||||
self.assertEquals(output2, 1.)
|
||||
|
||||
class SpectralFlatnessAnalysisTests(globalTests, NumericAssertions):
|
||||
"""Tests Spectral Crest Factor analysis generation."""
|
||||
|
||||
def setUp(self):
|
||||
self.sr = 44100
|
||||
self.f = 440
|
||||
x = np.arange(44100)
|
||||
sine_wave = np.sin(2*np.pi*self.f/self.sr*x)
|
||||
white_noise = np.random.random(44100)
|
||||
silence = np.zeros(44100)
|
||||
self.input = np.concatenate((sine_wave, white_noise, silence))
|
||||
self.silence = np.zeros(512)
|
||||
self.equal_mag = np.ones(512)
|
||||
self.peak = self.silence.copy()
|
||||
self.peak[256] = 1
|
||||
|
||||
def test_GenerateSpectralFlatness(self):
|
||||
fft = analysis.FFTAnalysis.stft(self.input, 512)
|
||||
output = analysis.SpectralFlatnessAnalysis.create_spcflatness_analysis(fft, 512, self.sr)
|
||||
# TODO: Write assertions for results. This isn't testing anything
|
||||
# otherwise...
|
||||
output = analysis.SpectralFlatnessAnalysis.create_spcflatness_analysis([self.silence])
|
||||
output1 = analysis.SpectralFlatnessAnalysis.create_spcflatness_analysis([self.equal_mag])
|
||||
output2 = analysis.SpectralFlatnessAnalysis.create_spcflatness_analysis([self.peak])
|
||||
|
||||
self.assertIsNaN(output)
|
||||
self.assertEqual(output1, 1.)
|
||||
self.assertEqual(output2, 0.)
|
||||
|
||||
class KurtosisAnalysisTests(globalTests):
|
||||
"""Tests Kurtosis analysis generation."""
|
||||
|
||||
Reference in New Issue
Block a user