Switch between audio channels

References #18.
This commit is contained in:
Alexander Kojevnikov 2016-04-05 21:25:06 -07:00
parent 7eef5eed6a
commit fe890b837d
5 changed files with 29 additions and 3 deletions

View File

@ -47,6 +47,9 @@ On OS X use the Command key instead of Ctrl.
## Spectrogram ## Spectrogram
`c`, `C`
: Change the audio channel.
`f`, `F` `f`, `F`
: Change the DFT window function. : Change the DFT window function.

View File

@ -25,6 +25,7 @@ struct spek_pipeline
{ {
std::unique_ptr<AudioFile> file; std::unique_ptr<AudioFile> file;
std::unique_ptr<FFTPlan> fft; std::unique_ptr<FFTPlan> fft;
int channel;
enum window_function window_function; enum window_function window_function;
int samples; int samples;
spek_pipeline_cb cb; spek_pipeline_cb cb;
@ -61,6 +62,7 @@ static void reader_sync(struct spek_pipeline *p, int pos);
struct spek_pipeline * spek_pipeline_open( struct spek_pipeline * spek_pipeline_open(
std::unique_ptr<AudioFile> file, std::unique_ptr<AudioFile> file,
std::unique_ptr<FFTPlan> fft, std::unique_ptr<FFTPlan> fft,
int channel,
enum window_function window_function, enum window_function window_function,
int samples, int samples,
spek_pipeline_cb cb, spek_pipeline_cb cb,
@ -70,6 +72,7 @@ struct spek_pipeline * spek_pipeline_open(
spek_pipeline *p = new spek_pipeline(); spek_pipeline *p = new spek_pipeline();
p->file = std::move(file); p->file = std::move(file);
p->fft = std::move(fft); p->fft = std::move(fft);
p->channel = channel;
p->window_function = window_function; p->window_function = window_function;
p->samples = samples; p->samples = samples;
p->cb = cb; p->cb = cb;
@ -95,7 +98,7 @@ struct spek_pipeline * spek_pipeline_open(
p->input_size = p->nfft * (NFFT * 2 + 1); p->input_size = p->nfft * (NFFT * 2 + 1);
p->input = (float*)malloc(p->input_size * sizeof(float)); p->input = (float*)malloc(p->input_size * sizeof(float));
p->output = (float*)malloc(p->fft->get_output_size() * sizeof(float)); p->output = (float*)malloc(p->fft->get_output_size() * sizeof(float));
p->file->start(0, samples); p->file->start(channel, samples);
} }
return p; return p;
@ -196,8 +199,8 @@ std::string spek_pipeline_desc(const struct spek_pipeline *pipeline)
if (pipeline->file->get_channels()) { if (pipeline->file->get_channels()) {
items.push_back(std::string( items.push_back(std::string(
wxString::Format( wxString::Format(
ngettext("%d channel", "%d channels", pipeline->file->get_channels()), // TRANSLATORS: first %d is the current channel, second %d is the total number.
pipeline->file->get_channels() "channel %d / %d", pipeline->channel + 1, pipeline->file->get_channels()
).utf8_str() ).utf8_str()
)); ));
} }
@ -273,6 +276,11 @@ std::string spek_pipeline_desc(const struct spek_pipeline *pipeline)
return desc; return desc;
} }
int spek_pipeline_channels(const struct spek_pipeline *pipeline)
{
return pipeline->file->get_channels();
}
double spek_pipeline_duration(const struct spek_pipeline *pipeline) double spek_pipeline_duration(const struct spek_pipeline *pipeline)
{ {
return pipeline->file->get_duration(); return pipeline->file->get_duration();

View File

@ -20,6 +20,7 @@ typedef void (*spek_pipeline_cb)(int bands, int sample, float *values, void *cb_
struct spek_pipeline * spek_pipeline_open( struct spek_pipeline * spek_pipeline_open(
std::unique_ptr<AudioFile> file, std::unique_ptr<AudioFile> file,
std::unique_ptr<FFTPlan> fft, std::unique_ptr<FFTPlan> fft,
int channel,
enum window_function window_function, enum window_function window_function,
int samples, int samples,
spek_pipeline_cb cb, spek_pipeline_cb cb,
@ -30,5 +31,6 @@ void spek_pipeline_start(struct spek_pipeline *pipeline);
void spek_pipeline_close(struct spek_pipeline *pipeline); void spek_pipeline_close(struct spek_pipeline *pipeline);
std::string spek_pipeline_desc(const struct spek_pipeline *pipeline); std::string spek_pipeline_desc(const struct spek_pipeline *pipeline);
int spek_pipeline_channels(const struct spek_pipeline *pipeline);
double spek_pipeline_duration(const struct spek_pipeline *pipeline); double spek_pipeline_duration(const struct spek_pipeline *pipeline);
int spek_pipeline_sample_rate(const struct spek_pipeline *pipeline); int spek_pipeline_sample_rate(const struct spek_pipeline *pipeline);

View File

@ -47,6 +47,8 @@ SpekSpectrogram::SpekSpectrogram(wxFrame *parent) :
audio(new Audio()), // TODO: refactor audio(new Audio()), // TODO: refactor
fft(new FFT()), fft(new FFT()),
pipeline(NULL), pipeline(NULL),
channels(0),
channel(0),
window_function(WINDOW_DEFAULT), window_function(WINDOW_DEFAULT),
duration(0.0), duration(0.0),
sample_rate(0), sample_rate(0),
@ -72,6 +74,7 @@ SpekSpectrogram::~SpekSpectrogram()
void SpekSpectrogram::open(const wxString& path) void SpekSpectrogram::open(const wxString& path)
{ {
this->path = path; this->path = path;
this->channel = 0;
start(); start();
Refresh(); Refresh();
} }
@ -88,6 +91,12 @@ void SpekSpectrogram::save(const wxString& path)
void SpekSpectrogram::on_char(wxKeyEvent& evt) void SpekSpectrogram::on_char(wxKeyEvent& evt)
{ {
switch (evt.GetKeyCode()) { switch (evt.GetKeyCode()) {
case 'C':
this->channel = (this->channel + 1) % this->channels;
break;
case 'c':
this->channel = (this->channel - 1 + this->channels) % this->channels;
break;
case 'F': case 'F':
this->window_function = (enum window_function) ((this->window_function + 1) % WINDOW_COUNT); this->window_function = (enum window_function) ((this->window_function + 1) % WINDOW_COUNT);
break; break;
@ -367,6 +376,7 @@ void SpekSpectrogram::start()
this->pipeline = spek_pipeline_open( this->pipeline = spek_pipeline_open(
this->audio->open(std::string(this->path.utf8_str())), this->audio->open(std::string(this->path.utf8_str())),
this->fft->create(this->fft_bits), this->fft->create(this->fft_bits),
this->channel,
this->window_function, this->window_function,
samples, samples,
pipeline_cb, pipeline_cb,
@ -375,6 +385,7 @@ void SpekSpectrogram::start()
spek_pipeline_start(this->pipeline); spek_pipeline_start(this->pipeline);
// TODO: extract conversion into a utility function. // TODO: extract conversion into a utility function.
this->desc = wxString::FromUTF8(spek_pipeline_desc(this->pipeline).c_str()); this->desc = wxString::FromUTF8(spek_pipeline_desc(this->pipeline).c_str());
this->channels = spek_pipeline_channels(this->pipeline);
this->duration = spek_pipeline_duration(this->pipeline); this->duration = spek_pipeline_duration(this->pipeline);
this->sample_rate = spek_pipeline_sample_rate(this->pipeline); this->sample_rate = spek_pipeline_sample_rate(this->pipeline);
} else { } else {

View File

@ -35,6 +35,8 @@ private:
std::unique_ptr<Audio> audio; std::unique_ptr<Audio> audio;
std::unique_ptr<FFT> fft; std::unique_ptr<FFT> fft;
spek_pipeline *pipeline; spek_pipeline *pipeline;
int channels;
int channel;
enum window_function window_function; enum window_function window_function;
wxString path; wxString path;
wxString desc; wxString desc;