Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
ale
imms
Commits
f3512603
Commit
f3512603
authored
Mar 23, 2013
by
ale
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add a stream-based analyzer interface
parent
c8c182e3
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
117 additions
and
1 deletion
+117
-1
analyzer/analyzer.cc
analyzer/analyzer.cc
+90
-1
analyzer/analyzer.h
analyzer/analyzer.h
+27
-0
No files found.
analyzer/analyzer.cc
View file @
f3512603
...
...
@@ -35,7 +35,96 @@ using std::cout;
using
std
::
cerr
;
using
std
::
endl
;
typedef
uint16_t
sample_t
;
#define STATE_PREFILL 0
#define STATE_RUN 1
StreamAnalyzer
::
StreamAnalyzer
()
:
hanwin
(
WINDOWSIZE
),
state
(
STATE_PREFILL
),
frames
(
0
),
buf_pos
(
0
),
outdata
(
NUMFREQS
)
{}
void
StreamAnalyzer
::
process
(
char
*
data
,
int
n
)
{
char
*
buf_head
=
(
char
*
)(
indata
+
OVERLAP
);
while
(
n
>
0
)
{
int
sz
=
sizeof
(
sample_t
)
*
READSIZE
-
buf_pos
;
if
(
n
<
sz
)
sz
=
n
;
memcpy
(
buf_head
+
buf_pos
,
data
,
sz
);
n
-=
sz
;
data
+=
sz
;
buf_pos
+=
sz
;
if
(
buf_pos
==
sizeof
(
sample_t
)
*
READSIZE
)
{
buf_pos
=
0
;
process_buffer
();
}
}
}
void
StreamAnalyzer
::
process_buffer
()
{
switch
(
state
)
{
case
STATE_PREFILL
:
state
=
STATE_RUN
;
break
;
case
STATE_RUN
:
process_buffer_internal
();
}
// shift the read data
memmove
(
indata
,
indata
+
READSIZE
,
OVERLAP
*
sizeof
(
sample_t
));
}
void
StreamAnalyzer
::
process_buffer_internal
()
{
if
(
++
frames
>
MAXFRAMES
)
return
;
// calculate MFCCs:
for
(
int
i
=
0
;
i
<
WINDOWSIZE
;
++
i
)
pcmfft
.
input
()[
i
]
=
(
double
)
indata
[
i
];
// window the data
hanwin
.
apply
(
pcmfft
.
input
(),
WINDOWSIZE
);
// fft to get the spectrum
pcmfft
.
execute
();
// calculate the power spectrum
for
(
int
i
=
0
;
i
<
NUMFREQS
;
++
i
)
outdata
[
i
]
=
pow
(
pcmfft
.
output
()[
i
][
0
],
2
)
+
pow
(
pcmfft
.
output
()[
i
][
1
],
2
);
// apply mel filter bank
vector
<
double
>
melfreqs
;
mfbank
.
apply
(
outdata
,
melfreqs
);
beatkeeper
.
process
(
melfreqs
);
// compute log energy
for
(
int
i
=
0
;
i
<
NUMMEL
;
++
i
)
melfreqs
[
i
]
=
log
(
melfreqs
[
i
]);
// another fft to get the MFCCs
specfft
.
apply
(
melfreqs
);
// discard the first mfcc
float
cepstrum
[
NUMCEPSTR
];
for
(
int
i
=
1
;
i
<=
NUMCEPSTR
;
++
i
)
cepstrum
[
i
-
1
]
=
specfft
.
output
()[
i
][
0
];
mfcckeeper
.
process
(
cepstrum
);
}
Features
*
StreamAnalyzer
::
get_result
()
{
if
(
frames
<
100
)
return
NULL
;
mfcckeeper
.
finalize
();
beatkeeper
.
finalize
();
return
new
Features
(
mfcckeeper
.
get_result
(),
beatkeeper
.
get_result
());
}
// Calculate acoustic stats for a song and write them to the database.
Features
*
Analyzer
::
analyze
(
int
infd
)
...
...
analyzer/analyzer.h
View file @
f3512603
...
...
@@ -57,4 +57,31 @@ protected:
HanningWindow
hanwin
;
};
typedef
uint16_t
sample_t
;
class
StreamAnalyzer
{
public:
StreamAnalyzer
();
void
process
(
char
*
data
,
int
n
);
Features
*
get_result
();
protected:
void
process_buffer
();
void
process_buffer_internal
();
FFTWisdom
wisdom
;
FFTProvider
<
WINDOWSIZE
>
pcmfft
;
FFTProvider
<
NUMMEL
>
specfft
;
MelFilterBank
mfbank
;
HanningWindow
hanwin
;
int
state
;
size_t
frames
;
int
buf_pos
;
sample_t
indata
[
WINDOWSIZE
];
vector
<
double
>
outdata
;
MFCCKeeper
mfcckeeper
;
BeatManager
beatkeeper
;
};
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment