Persist any error returned by JUCE during initialise() method, such as sample rate issues on Windows (when playback and recording sample rates do not match, which breaks WASAPI)

This commit is contained in:
Jonathan Thomas
2019-04-04 00:55:47 -05:00
parent 76e87e6145
commit 9dbb063ded
5 changed files with 71 additions and 45 deletions

View File

@@ -57,12 +57,15 @@ namespace openshot
class AudioDeviceManagerSingleton {
private:
/// Default constructor (Don't allow user to create an instance of this singleton)
AudioDeviceManagerSingleton(){};
AudioDeviceManagerSingleton(){ initialise_error=""; };
/// Private variable to keep track of singleton instance
static AudioDeviceManagerSingleton * m_pInstance;
public:
/// Error found during JUCE initialise method
string initialise_error;
/// Create or get an instance of this singleton (invoke the class with this method)
static AudioDeviceManagerSingleton * Instance(int numChannels);
@@ -78,52 +81,55 @@ namespace openshot
*/
class AudioPlaybackThread : Thread
{
AudioSourcePlayer player;
AudioTransportSource transport;
MixerAudioSource mixer;
AudioReaderSource *source;
double sampleRate;
int numChannels;
WaitableEvent play;
WaitableEvent played;
int buffer_size;
bool is_playing;
SafeTimeSliceThread time_thread;
/// Constructor
AudioPlaybackThread();
/// Destructor
~AudioPlaybackThread();
AudioSourcePlayer player;
AudioTransportSource transport;
MixerAudioSource mixer;
AudioReaderSource *source;
double sampleRate;
int numChannels;
WaitableEvent play;
WaitableEvent played;
int buffer_size;
bool is_playing;
SafeTimeSliceThread time_thread;
/// Set the current thread's reader
void Reader(ReaderBase *reader);
/// Constructor
AudioPlaybackThread();
/// Destructor
~AudioPlaybackThread();
/// Get the current frame object (which is filling the buffer)
std::shared_ptr<Frame> getFrame();
/// Set the current thread's reader
void Reader(ReaderBase *reader);
/// Get the current frame number being played
int64_t getCurrentFramePosition();
/// Get the current frame object (which is filling the buffer)
std::shared_ptr<Frame> getFrame();
/// Play the audio
void Play();
/// Get the current frame number being played
int64_t getCurrentFramePosition();
/// Seek the audio thread
void Seek(int64_t new_position);
/// Play the audio
void Play();
/// Stop the audio playback
void Stop();
/// Seek the audio thread
void Seek(int64_t new_position);
/// Start thread
void run();
/// Set Speed (The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...)
void setSpeed(int new_speed) { if (source) source->setSpeed(new_speed); }
/// Stop the audio playback
void Stop();
/// Get Speed (The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...)
int getSpeed() const { if (source) return source->getSpeed(); else return 1; }
/// Start thread
void run();
friend class PlayerPrivate;
friend class QtPlayer;
/// Set Speed (The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...)
void setSpeed(int new_speed) { if (source) source->setSpeed(new_speed); }
/// Get Speed (The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...)
int getSpeed() const { if (source) return source->getSpeed(); else return 1; }
/// Get Audio Error (if any)
string getError() { return AudioDeviceManagerSingleton::Instance(numChannels)->initialise_error; }
friend class PlayerPrivate;
friend class QtPlayer;
};
}

View File

@@ -59,6 +59,9 @@ namespace openshot
/// Close audio device
void CloseAudioDevice();
/// Get Error (if any)
string GetError();
/// Play the video
void Play();

View File

@@ -953,11 +953,15 @@ void Frame::Play()
return;
AudioDeviceManager deviceManager;
deviceManager.initialise (0, /* number of input channels */
String error = deviceManager.initialise (0, /* number of input channels */
2, /* number of output channels */
0, /* no XML settings.. */
true /* select default device on failure */);
//deviceManager.playTestSound();
// Output error (if any)
if (error.isNotEmpty()) {
cout << "Error on initialise(): " << error.toStdString() << endl;
}
AudioSourcePlayer audioSourcePlayer;
deviceManager.addAudioCallback (&audioSourcePlayer);

View File

@@ -42,11 +42,18 @@ namespace openshot
m_pInstance = new AudioDeviceManagerSingleton;
// Initialize audio device only 1 time
m_pInstance->audioDeviceManager.initialise (
String error = m_pInstance->audioDeviceManager.initialise (
0, /* number of input channels */
numChannels, /* number of output channels */
0, /* no XML settings.. */
true /* select default device on failure */);
// Persist any errors detected
if (error.isNotEmpty()) {
m_pInstance->initialise_error = error.toStdString();
} else {
m_pInstance->initialise_error = "";
}
}
return m_pInstance;

View File

@@ -59,12 +59,21 @@ void QtPlayer::CloseAudioDevice()
AudioDeviceManagerSingleton::Instance(0)->CloseAudioDevice();
}
// Return any error string during initialization
string QtPlayer::GetError() {
if (reader && threads_started) {
// Get error from audio thread (if any)
return p->audioPlayback->getError();
} else {
return "";
}
}
void QtPlayer::SetSource(const std::string &source)
{
FFmpegReader *ffreader = new FFmpegReader(source);
ffreader->DisplayInfo();
//reader = new FrameMapper(ffreader, ffreader->info.fps, PULLDOWN_NONE, ffreader->info.sample_rate, ffreader->info.channels, ffreader->info.channel_layout);
reader = new Timeline(ffreader->info.width, ffreader->info.height, ffreader->info.fps, ffreader->info.sample_rate, ffreader->info.channels, ffreader->info.channel_layout);
Clip *c = new Clip(source);
@@ -72,9 +81,6 @@ void QtPlayer::SetSource(const std::string &source)
tm->AddClip(c);
tm->Open();
// ZmqLogger::Instance()->Path("/home/jonathan/.openshot_qt/libopenshot.log");
// ZmqLogger::Instance()->Enable(true);
// Set the reader
Reader(reader);
}