aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--src/descriptors.c57
-rw-r--r--src/vector.c48
-rw-r--r--xtract/libxtract.h7
-rw-r--r--xtract/xtract_vector.h19
5 files changed, 110 insertions, 22 deletions
diff --git a/TODO b/TODO
index 39e1ea5..3861743 100644
--- a/TODO
+++ b/TODO
@@ -16,5 +16,4 @@ Use the fftw guru interface to create multipurpose global plans from xtract_fft_
Add LPC via Schur algorithm
If argv uses an integer, then it should point to a variable of type int. At the moment floats are used to store ints.
Write macro to truncate numbers <= 0 prior to taking log and integrate into functions across the library
-Add xtract_chords() - gets pitch classes from spectrum either as MIDI note numbers or pitch class and octave class - e.g. 'F#4' etc.
Add xtract_subbands() - gets subband power or subband magnitude for given bands
diff --git a/src/descriptors.c b/src/descriptors.c
index 4460de8..e96f467 100644
--- a/src/descriptors.c
+++ b/src/descriptors.c
@@ -86,7 +86,7 @@ xtract_function_descriptor_t *xtract_make_descriptors(void){
*argv_def = XTRACT_SR_DEFAULT;
*argv_unit = XTRACT_HERTZ;
break;
- /* argc = 2 */;
+ /* argc = 2 */;
case XTRACT_ROLLOFF:
*argv_min = XTRACT_FFT_BANDS_MIN;
*argv_max = XTRACT_FFT_BANDS_MAX;
@@ -97,24 +97,6 @@ xtract_function_descriptor_t *xtract_make_descriptors(void){
*(argv_def + 1) = 95.f;
*(argv_unit + 1) = XTRACT_PERCENT;
break;
- case XTRACT_SPECTRUM:
- *argv_min = XTRACT_SR_LOWER_LIMIT / XTRACT_FFT_BANDS_MIN;
- *argv_max = XTRACT_SR_UPPER_LIMIT / XTRACT_FFT_BANDS_MAX;
- *argv_def = XTRACT_SR_DEFAULT / XTRACT_FFT_BANDS_DEF;
- *argv_unit = XTRACT_HERTZ;
- *(argv_min + 1) = 0;
- *(argv_max + 1) = 3 ;
- *(argv_def + 1) = 0;
- *(argv_unit + 1) = XTRACT_NONE;
- *(argv_min + 2) = 0;
- *(argv_max + 2) = 1;
- *(argv_def + 2) = 0;
- *(argv_unit + 2) = XTRACT_NONE;
- *(argv_min + 3) = 0;
- *(argv_max + 3) = 1;
- *(argv_def + 3) = 0;
- *(argv_unit + 3) = XTRACT_NONE;
- break;
case XTRACT_PEAK_SPECTRUM:
*argv_min = XTRACT_SR_LOWER_LIMIT / 2;
*argv_max = XTRACT_SR_UPPER_LIMIT / 2;
@@ -150,6 +132,43 @@ xtract_function_descriptor_t *xtract_make_descriptors(void){
*(argv_def + 1) = XTRACT_NONE;
*(argv_unit + 1) = XTRACT_NONE;
break;
+ /* argc = 4 */
+ case XTRACT_SPECTRUM:
+ *argv_min = XTRACT_SR_LOWER_LIMIT / XTRACT_FFT_BANDS_MIN;
+ *argv_max = XTRACT_SR_UPPER_LIMIT / XTRACT_FFT_BANDS_MAX;
+ *argv_def = XTRACT_SR_DEFAULT / XTRACT_FFT_BANDS_DEF;
+ *argv_unit = XTRACT_HERTZ;
+ *(argv_min + 1) = 0;
+ *(argv_max + 1) = 3 ;
+ *(argv_def + 1) = 0;
+ *(argv_unit + 1) = XTRACT_NONE;
+ *(argv_min + 2) = 0;
+ *(argv_max + 2) = 1;
+ *(argv_def + 2) = 0;
+ *(argv_unit + 2) = XTRACT_NONE;
+ *(argv_min + 3) = 0;
+ *(argv_max + 3) = 1;
+ *(argv_def + 3) = 0;
+ *(argv_unit + 3) = XTRACT_NONE;
+ break;
+ case XTRACT_SUBBANDS:
+ *argv_min = XTRACT_ANY;
+ *argv_max = XTRACT_ANY;
+ *argv_def = XTRACT_MEAN;
+ *argv_unit = XTRACT_NONE;
+ *(argv_min + 1) = 1;
+ *(argv_max + 1) = 16384;
+ *(argv_def + 1) = 4;
+ *(argv_unit + 1) = XTRACT_NONE;
+ *(argv_min + 2) = 0;
+ *(argv_max + 2) = 32;
+ *(argv_def + 2) = 0;
+ *(argv_unit + 2) = XTRACT_NONE;
+ *(argv_min + 3) = 0;
+ *(argv_max + 3) = 1;
+ *(argv_def + 3) = 0;
+ *(argv_unit + 3) = XTRACT_NONE;
+ break;
case XTRACT_BARK_COEFFICIENTS:
/* BARK_COEFFICIENTS is special because argc = BARK_BANDS */
case XTRACT_WINDOWED:
diff --git a/src/vector.c b/src/vector.c
index ce74630..97a876b 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -573,4 +573,52 @@ int xtract_lpcc(const float *data, const int N, const void *argv, float *result)
// return XTRACT_SUCCESS;
//}
+int xtract_subbands(const float *data, const int N, const void *argv, float *result){
+
+ int n, bw, xtract_func, nbands, scale, start, lower, *argi, rv;
+
+ argi = (int *)argv;
+
+ xtract_func = argi[0];
+ nbands = argi[1];
+ scale = argi[2];
+ start = argi[3];
+
+
+ if(scale == XTRACT_LINEAR_SUBBANDS)
+ bw = floorf((N - start) / nbands);
+ else
+ bw = start;
+
+ lower = start;
+
+ for(n = 0; n < nbands; n++){
+
+ /* Bounds sanity check */
+ if(lower + bw >= N)
+ result[n] = 0.f
+ continue;
+
+ rv = xtract[xtract_func](data+lower, bw, NULL, &result[n]);
+
+ if(rv != XTRACT_SUCCESS)
+ return rv;
+
+ switch(scale){
+ case XTRACT_OCTAVE_SUBBANDS:
+ lower += bw;
+ bw = lower;
+ break;
+ case XTRACT_LINEAR_SUBBANDS:
+ lower += bw;
+ break;
+ }
+
+ }
+
+ return rv;
+
+}
+
+
diff --git a/xtract/libxtract.h b/xtract/libxtract.h
index 2fad148..44b3828 100644
--- a/xtract/libxtract.h
+++ b/xtract/libxtract.h
@@ -130,6 +130,7 @@ enum xtract_features_ {
XTRACT_HARMONIC_SPECTRUM,
XTRACT_LPC,
XTRACT_LPCC,
+ XTRACT_SUBBANDS,
/* Helper functions */
XTRACT_WINDOWED
};
@@ -179,6 +180,12 @@ enum xtract_spectrum_ {
XTRACT_LOG_POWER_SPECTRUM
};
+/** \brief Subband scales */
+enum xtract_subband_scales_ {
+ XTRACT_OCTAVE_SUBBANDS,
+ XTRACT_LINEAR_SUBBANDS
+};
+
/** \brief Enumeration of data types*/
typedef enum type_ {
XTRACT_FLOAT,
diff --git a/xtract/xtract_vector.h b/xtract/xtract_vector.h
index 07bf176..1d68080 100644
--- a/xtract/xtract_vector.h
+++ b/xtract/xtract_vector.h
@@ -158,8 +158,23 @@ int xtract_lpc(const float *data, const int N, const void *argv, float *result);
*/
int xtract_lpcc(const float *data, const int N, const void *argv, float *result);
-
-
+/** \brief Extract subbands from a spectrum
+ *
+ * \param *data: a pointer to an array of size N containing N magnitude/power/log magnitude/log power coefficients. (e.g. the first half of the array pointed to by *result from xtract_spectrum().
+ * \param N: the number of elements from the array pointed to by *data to be considered
+ * \param *argv: A pointer to an array containing four integers. The first represents the extraction function to applied to each subband e.g. XTRACT_SUM or XTRACT_MEAN, the second represents the number of subbands required, and the third represents the frequency scale to be used for the subband bounds as defined in the enumeration xtract_subband_scales_ (libxtract.h). The fourth integer represent the start point of the subbands as a location in the input array as pointed to by *data (e.g. a value of 5 would start the subband extraction at bin 5)
+ * \param *result: A pointer to an array containing the resultant subband values. The calling function is responsible for allocating and freeing memory for *result. xtract_subbands() assumes that at least argv[1] * sizeof(float) bytes have been allocated. If the requested nbands extends the subband range beyond N, then the remaining bands will be set to 0. If the array pointed to by *result has more than argv[1] elements, the superfluous elements will be unchanged.
+ *
+ * xtract_subbands() divides a spectrum into subbands and applies the function given by argv[0] to the values in each subband to give a 'reduced' representation of the spectrum as *result
+ *
+ * Specifying XTRACT_OCTAVE_SUBBANDS will extract subbands at each octave from the start bin until argv[1] is reached or N is reached
+ * Specifying XTRACT_LINEAR_SUBBANDS will extract argv[1] equal sized subbands between the start bin and N
+ *
+ *
+ * It is assumed that a sensible function will be given in argv[0], and for this function argv will always be NULL. Sensible values for argv[0] are XTRACT_MEAN and XTRACT_SUM, although something like XTRACT_IRREGULARITY_K might yield interesting results.
+ *
+ */
+int xtract_subbands(const float *data, const int N, const void *argv, float *result);
/** @} */
#ifdef __cplusplus