Hello,
I know I’ve posted with a little confusion around this before, sorry for any redundancy, but the issue is a bit clearer.
Using a WebInputStream into an AudioFormatManager to generate a Reader creates what seems like multiple unnecessary downloads from the InputStream.
Here is a test app showing the issue. Hitting the download button begins a download which seems to occur twice before the FormatManager is able to read from it. It then appears that the FormatManager reads the stream a third time, meaning that to download an audio file and play it, the app is needing to download it three times!
Here is some code based from the GUI App template:
MainComponent.h:
class MainContentComponent : public Component,
public Thread,
public Button::Listener,
public Timer
{
public:
//==============================================================================
MainContentComponent();
~MainContentComponent();
void paint (Graphics&) override;
void timerCallback() override;
void buttonClicked(Button *b) override;
void run() override;
private:
ScopedPointer<TextButton> downloadFileBtn;
void downloadFile();
ScopedPointer<AudioFormatManager> formatManager;
InputStream* audioInputStream;
AudioSampleBuffer downloadBuffer;
bool fileLoaded = false;
bool downloading = false;
bool buffering = false;
bool threadFirstRun = true;
int totalLength = 0;
int currentPosition = 0;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
MainComponent.cpp
//==============================================================================
MainContentComponent::MainContentComponent() : Thread("Thread"),
audioInputStream(nullptr)
{
setSize (300, 100);
downloadFileBtn = new TextButton("Download");
downloadFileBtn->setBounds(0, 0, getWidth(), getHeight()/2);
downloadFileBtn->addListener(this);
addAndMakeVisible(downloadFileBtn);
formatManager = new AudioFormatManager;
formatManager->registerBasicFormats();
}
MainContentComponent::~MainContentComponent()
{
}
void MainContentComponent::paint (Graphics& g)
{
if (audioInputStream != nullptr)
{
g.fillAll(Colours::black);
g.setColour(Colours::red);
float width = jmap((float)currentPosition, 0.0f, (float)totalLength, 0.0f, (float)getWidth());
g.fillRect(0, getHeight()/2, (int)width, getHeight()/2);
}
else
{
g.fillAll(Colours::black);
}
}
void MainContentComponent::timerCallback()
{
if (audioInputStream != nullptr)
{
currentPosition = audioInputStream->getPosition();
totalLength = audioInputStream->getTotalLength();
if (totalLength < 1)
totalLength = currentPosition + 1;
DBG("CURRENT POSITION: " << currentPosition);
DBG("TOTAL LENGTH: " << totalLength);
repaint();
}
}
void MainContentComponent::buttonClicked(juce::Button *b)
{
if (b == downloadFileBtn)
startThread();
}
void MainContentComponent::run()
{
while (! threadShouldExit())
{
DBG("THREAD RUN");
if (threadFirstRun == true)
{
threadFirstRun = false;
downloadFile();
}
else
{
signalThreadShouldExit();
}
}
}
void MainContentComponent::downloadFile()
{
DBG("DOWNLOAD");
if (fileLoaded != true)
{
startTimer(50);
downloading = true;
URL theURL("https://jakemumu.github.io/08.wav");
ScopedPointer<AudioFormatReader> reader;
reader = formatManager->createReaderFor(audioInputStream = theURL.createInputStream(false));
if (reader != nullptr)
{
downloading = false;
buffering = true;
downloadBuffer.setSize(reader->numChannels, reader->lengthInSamples);
reader->read(&downloadBuffer, 0, reader->lengthInSamples, 0, true, true);
DBG("FILE LOADED");
fileLoaded = true;
buffering = false;
stopTimer();
signalThreadShouldExit();
}
}
}
Note you may have to run the app twice to get this behavior, but it is a regular occurence. My setup is currently OS X El Capitan btw.