From 928dd723ca3f98aa9b013f2f6b0dd7776db61d0c Mon Sep 17 00:00:00 2001
From: Alexander Kojevnikov <alexander@kojevnikov.com>
Date: Sun, 24 Apr 2016 19:03:25 -0700
Subject: [PATCH] Switch between audio streams

References #18.
---
 MANUAL.md               |  3 +++
 src/spek-pipeline.cc    |  5 +++++
 src/spek-pipeline.h     |  1 +
 src/spek-spectrogram.cc | 24 +++++++++++++++++++++---
 src/spek-spectrogram.h  |  2 ++
 5 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/MANUAL.md b/MANUAL.md
index d802ed9..2520243 100644
--- a/MANUAL.md
+++ b/MANUAL.md
@@ -59,6 +59,9 @@ On OS X use the Command key instead of Ctrl.
 `p`, `P`
 :   Change the palette.
 
+`s`, `S`
+:   Change the audio stream.
+
 `u`, `U`
 :   Change the upper limit of the dynamic range in dBFS.
 
diff --git a/src/spek-pipeline.cc b/src/spek-pipeline.cc
index 54f232b..f0c3355 100644
--- a/src/spek-pipeline.cc
+++ b/src/spek-pipeline.cc
@@ -278,6 +278,11 @@ std::string spek_pipeline_desc(const struct spek_pipeline *pipeline)
     return desc;
 }
 
+int spek_pipeline_streams(const struct spek_pipeline *pipeline)
+{
+    return pipeline->file->get_streams();
+}
+
 int spek_pipeline_channels(const struct spek_pipeline *pipeline)
 {
     return pipeline->file->get_channels();
diff --git a/src/spek-pipeline.h b/src/spek-pipeline.h
index 8f45b8f..1df44c7 100644
--- a/src/spek-pipeline.h
+++ b/src/spek-pipeline.h
@@ -31,6 +31,7 @@ void spek_pipeline_start(struct spek_pipeline *pipeline);
 void spek_pipeline_close(struct spek_pipeline *pipeline);
 
 std::string spek_pipeline_desc(const struct spek_pipeline *pipeline);
+int spek_pipeline_streams(const struct spek_pipeline *pipeline);
 int spek_pipeline_channels(const struct spek_pipeline *pipeline);
 double spek_pipeline_duration(const struct spek_pipeline *pipeline);
 int spek_pipeline_sample_rate(const struct spek_pipeline *pipeline);
diff --git a/src/spek-spectrogram.cc b/src/spek-spectrogram.cc
index 34d4708..17becaa 100644
--- a/src/spek-spectrogram.cc
+++ b/src/spek-spectrogram.cc
@@ -47,6 +47,8 @@ SpekSpectrogram::SpekSpectrogram(wxFrame *parent) :
     audio(new Audio()), // TODO: refactor
     fft(new FFT()),
     pipeline(NULL),
+    streams(0),
+    stream(0),
     channels(0),
     channel(0),
     window_function(WINDOW_DEFAULT),
@@ -74,6 +76,7 @@ SpekSpectrogram::~SpekSpectrogram()
 void SpekSpectrogram::open(const wxString& path)
 {
     this->path = path;
+    this->stream = 0;
     this->channel = 0;
     start();
     Refresh();
@@ -92,10 +95,14 @@ void SpekSpectrogram::on_char(wxKeyEvent& evt)
 {
     switch (evt.GetKeyCode()) {
     case 'c':
-        this->channel = (this->channel + 1) % this->channels;
+        if (this->channels) {
+            this->channel = (this->channel + 1) % this->channels;
+        }
         break;
     case 'C':
-        this->channel = (this->channel - 1 + this->channels) % this->channels;
+        if (this->channels) {
+            this->channel = (this->channel - 1 + this->channels) % this->channels;
+        }
         break;
     case 'f':
         this->window_function = (enum window_function) ((this->window_function + 1) % WINDOW_COUNT);
@@ -118,6 +125,16 @@ void SpekSpectrogram::on_char(wxKeyEvent& evt)
         this->palette = (enum palette) ((this->palette - 1 + PALETTE_COUNT) % PALETTE_COUNT);
         this->create_palette();
         break;
+    case 's':
+        if (this->streams) {
+            this->stream = (this->stream + 1) % this->streams;
+        }
+        break;
+    case 'S':
+        if (this->streams) {
+            this->stream = (this->stream - 1 + this->streams) % this->streams;
+        }
+        break;
     case 'u':
         this->urange = spek_min(this->urange + 1, MAX_RANGE);
         break;
@@ -374,7 +391,7 @@ void SpekSpectrogram::start()
     if (samples > 0) {
         this->image.Create(samples, bits_to_bands(this->fft_bits));
         this->pipeline = spek_pipeline_open(
-            this->audio->open(std::string(this->path.utf8_str()), 0),
+            this->audio->open(std::string(this->path.utf8_str()), this->stream),
             this->fft->create(this->fft_bits),
             this->channel,
             this->window_function,
@@ -385,6 +402,7 @@ void SpekSpectrogram::start()
         spek_pipeline_start(this->pipeline);
         // TODO: extract conversion into a utility function.
         this->desc = wxString::FromUTF8(spek_pipeline_desc(this->pipeline).c_str());
+        this->streams = spek_pipeline_streams(this->pipeline);
         this->channels = spek_pipeline_channels(this->pipeline);
         this->duration = spek_pipeline_duration(this->pipeline);
         this->sample_rate = spek_pipeline_sample_rate(this->pipeline);
diff --git a/src/spek-spectrogram.h b/src/spek-spectrogram.h
index 6d03772..7e6b38c 100644
--- a/src/spek-spectrogram.h
+++ b/src/spek-spectrogram.h
@@ -35,6 +35,8 @@ private:
     std::unique_ptr<Audio> audio;
     std::unique_ptr<FFT> fft;
     spek_pipeline *pipeline;
+    int streams;
+    int stream;
     int channels;
     int channel;
     enum window_function window_function;