mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-23 01:44:22 +00:00
Added latency estimation for ALSA. Minor tweaks to TemporaryFile and some comments.
This commit is contained in:
parent
4328472028
commit
02eb45ddf7
7 changed files with 135 additions and 174 deletions
|
|
@ -8282,18 +8282,18 @@ void TemporaryFile::createTempFile (const File& parentDirectory, String name,
|
|||
|
||||
TemporaryFile::~TemporaryFile()
|
||||
{
|
||||
// Have a few attempts at deleting the file before giving up..
|
||||
for (int i = 5; --i >= 0;)
|
||||
if (! deleteTemporaryFile())
|
||||
{
|
||||
if (temporaryFile.deleteFile())
|
||||
return;
|
||||
/* Failed to delete our temporary file! The most likely reason for this would be
|
||||
that you've not closed an output stream that was being used to write to file.
|
||||
|
||||
Thread::sleep (50);
|
||||
If you find that something beyond your control is changing permissions on
|
||||
your temporary files and preventing them from being deleted, you may want to
|
||||
call TemporaryFile::deleteTemporaryFile() to detect those error cases and
|
||||
handle them appropriately.
|
||||
*/
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
// Failed to delete our temporary file! Check that you've deleted all the
|
||||
// file output streams that were using it!
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
bool TemporaryFile::overwriteTargetFileWithTemporary() const
|
||||
|
|
@ -8323,6 +8323,20 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TemporaryFile::deleteTemporaryFile() const
|
||||
{
|
||||
// Have a few attempts at deleting the file before giving up..
|
||||
for (int i = 5; --i >= 0;)
|
||||
{
|
||||
if (temporaryFile.deleteFile())
|
||||
return true;
|
||||
|
||||
Thread::sleep (50);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
/*** End of inlined file: juce_TemporaryFile.cpp ***/
|
||||
|
||||
|
|
@ -260050,6 +260064,7 @@ public:
|
|||
: handle (0),
|
||||
bitDepth (16),
|
||||
numChannelsRunning (0),
|
||||
latency (0),
|
||||
isInput (forInput),
|
||||
sampleFormat (AudioDataConverters::int16LE)
|
||||
{
|
||||
|
|
@ -260125,6 +260140,14 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
snd_pcm_uframes_t frames = 0;
|
||||
|
||||
if (failed (snd_pcm_hw_params_get_period_size (hwParams, &frames, &dir))
|
||||
|| failed (snd_pcm_hw_params_get_periods (hwParams, &periods, &dir)))
|
||||
latency = 0;
|
||||
else
|
||||
latency = frames * (periods - 1); // (this is the method JACK uses to guess the latency..)
|
||||
|
||||
snd_pcm_sw_params_t* swParams;
|
||||
snd_pcm_sw_params_alloca (&swParams);
|
||||
snd_pcm_uframes_t boundary;
|
||||
|
|
@ -260241,7 +260264,7 @@ public:
|
|||
|
||||
snd_pcm_t* handle;
|
||||
String error;
|
||||
int bitDepth, numChannelsRunning;
|
||||
int bitDepth, numChannelsRunning, latency;
|
||||
|
||||
private:
|
||||
const bool isInput;
|
||||
|
|
@ -260268,6 +260291,8 @@ public:
|
|||
: Thread ("Juce ALSA"),
|
||||
sampleRate (0),
|
||||
bufferSize (0),
|
||||
outputLatency (0),
|
||||
inputLatency (0),
|
||||
callback (0),
|
||||
inputId (inputId_),
|
||||
outputId (outputId_),
|
||||
|
|
@ -260349,6 +260374,8 @@ public:
|
|||
outputDevice = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
outputLatency = outputDevice->latency;
|
||||
}
|
||||
|
||||
if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty())
|
||||
|
|
@ -260372,6 +260399,8 @@ public:
|
|||
inputDevice = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
inputLatency = inputDevice->latency;
|
||||
}
|
||||
|
||||
if (outputDevice == 0 && inputDevice == 0)
|
||||
|
|
@ -260494,7 +260523,7 @@ public:
|
|||
|
||||
String error;
|
||||
double sampleRate;
|
||||
int bufferSize;
|
||||
int bufferSize, outputLatency, inputLatency;
|
||||
BigInteger currentInputChans, currentOutputChans;
|
||||
|
||||
Array <int> sampleRates;
|
||||
|
|
@ -260567,30 +260596,14 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
const StringArray getOutputChannelNames()
|
||||
{
|
||||
return internal.channelNamesOut;
|
||||
}
|
||||
const StringArray getOutputChannelNames() { return internal.channelNamesOut; }
|
||||
const StringArray getInputChannelNames() { return internal.channelNamesIn; }
|
||||
|
||||
const StringArray getInputChannelNames()
|
||||
{
|
||||
return internal.channelNamesIn;
|
||||
}
|
||||
int getNumSampleRates() { return internal.sampleRates.size(); }
|
||||
double getSampleRate (int index) { return internal.sampleRates [index]; }
|
||||
|
||||
int getNumSampleRates()
|
||||
{
|
||||
return internal.sampleRates.size();
|
||||
}
|
||||
|
||||
double getSampleRate (int index)
|
||||
{
|
||||
return internal.sampleRates [index];
|
||||
}
|
||||
|
||||
int getNumBufferSizesAvailable()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
int getDefaultBufferSize() { return 512; }
|
||||
int getNumBufferSizesAvailable() { return 50; }
|
||||
|
||||
int getBufferSizeSamples (int index)
|
||||
{
|
||||
|
|
@ -260604,11 +260617,6 @@ public:
|
|||
return n;
|
||||
}
|
||||
|
||||
int getDefaultBufferSize()
|
||||
{
|
||||
return 512;
|
||||
}
|
||||
|
||||
const String open (const BigInteger& inputChannels,
|
||||
const BigInteger& outputChannels,
|
||||
double sampleRate,
|
||||
|
|
@ -260645,45 +260653,19 @@ public:
|
|||
isOpen_ = false;
|
||||
}
|
||||
|
||||
bool isOpen()
|
||||
{
|
||||
return isOpen_;
|
||||
}
|
||||
bool isOpen() { return isOpen_; }
|
||||
bool isPlaying() { return isStarted && internal.error.isEmpty(); }
|
||||
const String getLastError() { return internal.error; }
|
||||
|
||||
int getCurrentBufferSizeSamples()
|
||||
{
|
||||
return internal.bufferSize;
|
||||
}
|
||||
int getCurrentBufferSizeSamples() { return internal.bufferSize; }
|
||||
double getCurrentSampleRate() { return internal.sampleRate; }
|
||||
int getCurrentBitDepth() { return internal.getBitDepth(); }
|
||||
|
||||
double getCurrentSampleRate()
|
||||
{
|
||||
return internal.sampleRate;
|
||||
}
|
||||
const BigInteger getActiveOutputChannels() const { return internal.currentOutputChans; }
|
||||
const BigInteger getActiveInputChannels() const { return internal.currentInputChans; }
|
||||
|
||||
int getCurrentBitDepth()
|
||||
{
|
||||
return internal.getBitDepth();
|
||||
}
|
||||
|
||||
const BigInteger getActiveOutputChannels() const
|
||||
{
|
||||
return internal.currentOutputChans;
|
||||
}
|
||||
|
||||
const BigInteger getActiveInputChannels() const
|
||||
{
|
||||
return internal.currentInputChans;
|
||||
}
|
||||
|
||||
int getOutputLatencyInSamples()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getInputLatencyInSamples()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int getOutputLatencyInSamples() { return internal.outputLatency; }
|
||||
int getInputLatencyInSamples() { return internal.inputLatency; }
|
||||
|
||||
void start (AudioIODeviceCallback* callback)
|
||||
{
|
||||
|
|
@ -260708,16 +260690,6 @@ public:
|
|||
oldCallback->audioDeviceStopped();
|
||||
}
|
||||
|
||||
bool isPlaying()
|
||||
{
|
||||
return isStarted && internal.error.isEmpty();
|
||||
}
|
||||
|
||||
const String getLastError()
|
||||
{
|
||||
return internal.error;
|
||||
}
|
||||
|
||||
String inputId, outputId;
|
||||
|
||||
private:
|
||||
|
|
@ -260750,8 +260722,8 @@ public:
|
|||
outputNames.clear();
|
||||
outputIds.clear();
|
||||
|
||||
snd_ctl_t* handle;
|
||||
snd_ctl_card_info_t* info;
|
||||
snd_ctl_t* handle = 0;
|
||||
snd_ctl_card_info_t* info = 0;
|
||||
snd_ctl_card_info_alloca (&info);
|
||||
|
||||
int cardNum = -1;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 51
|
||||
#define JUCE_BUILDNUMBER 52
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
@ -15897,6 +15897,11 @@ public:
|
|||
*/
|
||||
bool overwriteTargetFileWithTemporary() const;
|
||||
|
||||
/** Attempts to delete the temporary file, if it exists.
|
||||
@returns true if the file is successfully deleted (or if it didn't exist).
|
||||
*/
|
||||
bool deleteTemporaryFile() const;
|
||||
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
|
|
@ -19140,6 +19145,10 @@ public:
|
|||
|
||||
This is only needed in special circumstances for up-to-date modifier information
|
||||
at times when the app's event loop isn't running normally.
|
||||
|
||||
Another reason to avoid this method is that it's not stateless, and calling it may
|
||||
update the value returned by getCurrentModifiers(), which could cause subtle changes
|
||||
in the behaviour of some components.
|
||||
*/
|
||||
static const ModifierKeys getCurrentModifiersRealtime() throw();
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 51
|
||||
#define JUCE_BUILDNUMBER 52
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
|
|||
|
|
@ -191,6 +191,10 @@ public:
|
|||
|
||||
This is only needed in special circumstances for up-to-date modifier information
|
||||
at times when the app's event loop isn't running normally.
|
||||
|
||||
Another reason to avoid this method is that it's not stateless, and calling it may
|
||||
update the value returned by getCurrentModifiers(), which could cause subtle changes
|
||||
in the behaviour of some components.
|
||||
*/
|
||||
static const ModifierKeys getCurrentModifiersRealtime() throw();
|
||||
|
||||
|
|
|
|||
|
|
@ -64,18 +64,18 @@ void TemporaryFile::createTempFile (const File& parentDirectory, String name,
|
|||
|
||||
TemporaryFile::~TemporaryFile()
|
||||
{
|
||||
// Have a few attempts at deleting the file before giving up..
|
||||
for (int i = 5; --i >= 0;)
|
||||
if (! deleteTemporaryFile())
|
||||
{
|
||||
if (temporaryFile.deleteFile())
|
||||
return;
|
||||
/* Failed to delete our temporary file! The most likely reason for this would be
|
||||
that you've not closed an output stream that was being used to write to file.
|
||||
|
||||
Thread::sleep (50);
|
||||
If you find that something beyond your control is changing permissions on
|
||||
your temporary files and preventing them from being deleted, you may want to
|
||||
call TemporaryFile::deleteTemporaryFile() to detect those error cases and
|
||||
handle them appropriately.
|
||||
*/
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
// Failed to delete our temporary file! Check that you've deleted all the
|
||||
// file output streams that were using it!
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -106,5 +106,18 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TemporaryFile::deleteTemporaryFile() const
|
||||
{
|
||||
// Have a few attempts at deleting the file before giving up..
|
||||
for (int i = 5; --i >= 0;)
|
||||
{
|
||||
if (temporaryFile.deleteFile())
|
||||
return true;
|
||||
|
||||
Thread::sleep (50);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -143,6 +143,11 @@ public:
|
|||
*/
|
||||
bool overwriteTargetFileWithTemporary() const;
|
||||
|
||||
/** Attempts to delete the temporary file, if it exists.
|
||||
@returns true if the file is successfully deleted (or if it didn't exist).
|
||||
*/
|
||||
bool deleteTemporaryFile() const;
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ public:
|
|||
: handle (0),
|
||||
bitDepth (16),
|
||||
numChannelsRunning (0),
|
||||
latency (0),
|
||||
isInput (forInput),
|
||||
sampleFormat (AudioDataConverters::int16LE)
|
||||
{
|
||||
|
|
@ -198,6 +199,14 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
snd_pcm_uframes_t frames = 0;
|
||||
|
||||
if (failed (snd_pcm_hw_params_get_period_size (hwParams, &frames, &dir))
|
||||
|| failed (snd_pcm_hw_params_get_periods (hwParams, &periods, &dir)))
|
||||
latency = 0;
|
||||
else
|
||||
latency = frames * (periods - 1); // (this is the method JACK uses to guess the latency..)
|
||||
|
||||
snd_pcm_sw_params_t* swParams;
|
||||
snd_pcm_sw_params_alloca (&swParams);
|
||||
snd_pcm_uframes_t boundary;
|
||||
|
|
@ -316,7 +325,7 @@ public:
|
|||
|
||||
snd_pcm_t* handle;
|
||||
String error;
|
||||
int bitDepth, numChannelsRunning;
|
||||
int bitDepth, numChannelsRunning, latency;
|
||||
|
||||
//==============================================================================
|
||||
private:
|
||||
|
|
@ -346,6 +355,8 @@ public:
|
|||
: Thread ("Juce ALSA"),
|
||||
sampleRate (0),
|
||||
bufferSize (0),
|
||||
outputLatency (0),
|
||||
inputLatency (0),
|
||||
callback (0),
|
||||
inputId (inputId_),
|
||||
outputId (outputId_),
|
||||
|
|
@ -427,6 +438,8 @@ public:
|
|||
outputDevice = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
outputLatency = outputDevice->latency;
|
||||
}
|
||||
|
||||
if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty())
|
||||
|
|
@ -450,6 +463,8 @@ public:
|
|||
inputDevice = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
inputLatency = inputDevice->latency;
|
||||
}
|
||||
|
||||
if (outputDevice == 0 && inputDevice == 0)
|
||||
|
|
@ -573,7 +588,7 @@ public:
|
|||
|
||||
String error;
|
||||
double sampleRate;
|
||||
int bufferSize;
|
||||
int bufferSize, outputLatency, inputLatency;
|
||||
BigInteger currentInputChans, currentOutputChans;
|
||||
|
||||
Array <int> sampleRates;
|
||||
|
|
@ -648,30 +663,14 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
const StringArray getOutputChannelNames()
|
||||
{
|
||||
return internal.channelNamesOut;
|
||||
}
|
||||
const StringArray getOutputChannelNames() { return internal.channelNamesOut; }
|
||||
const StringArray getInputChannelNames() { return internal.channelNamesIn; }
|
||||
|
||||
const StringArray getInputChannelNames()
|
||||
{
|
||||
return internal.channelNamesIn;
|
||||
}
|
||||
int getNumSampleRates() { return internal.sampleRates.size(); }
|
||||
double getSampleRate (int index) { return internal.sampleRates [index]; }
|
||||
|
||||
int getNumSampleRates()
|
||||
{
|
||||
return internal.sampleRates.size();
|
||||
}
|
||||
|
||||
double getSampleRate (int index)
|
||||
{
|
||||
return internal.sampleRates [index];
|
||||
}
|
||||
|
||||
int getNumBufferSizesAvailable()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
int getDefaultBufferSize() { return 512; }
|
||||
int getNumBufferSizesAvailable() { return 50; }
|
||||
|
||||
int getBufferSizeSamples (int index)
|
||||
{
|
||||
|
|
@ -685,11 +684,6 @@ public:
|
|||
return n;
|
||||
}
|
||||
|
||||
int getDefaultBufferSize()
|
||||
{
|
||||
return 512;
|
||||
}
|
||||
|
||||
const String open (const BigInteger& inputChannels,
|
||||
const BigInteger& outputChannels,
|
||||
double sampleRate,
|
||||
|
|
@ -726,45 +720,19 @@ public:
|
|||
isOpen_ = false;
|
||||
}
|
||||
|
||||
bool isOpen()
|
||||
{
|
||||
return isOpen_;
|
||||
}
|
||||
bool isOpen() { return isOpen_; }
|
||||
bool isPlaying() { return isStarted && internal.error.isEmpty(); }
|
||||
const String getLastError() { return internal.error; }
|
||||
|
||||
int getCurrentBufferSizeSamples()
|
||||
{
|
||||
return internal.bufferSize;
|
||||
}
|
||||
int getCurrentBufferSizeSamples() { return internal.bufferSize; }
|
||||
double getCurrentSampleRate() { return internal.sampleRate; }
|
||||
int getCurrentBitDepth() { return internal.getBitDepth(); }
|
||||
|
||||
double getCurrentSampleRate()
|
||||
{
|
||||
return internal.sampleRate;
|
||||
}
|
||||
const BigInteger getActiveOutputChannels() const { return internal.currentOutputChans; }
|
||||
const BigInteger getActiveInputChannels() const { return internal.currentInputChans; }
|
||||
|
||||
int getCurrentBitDepth()
|
||||
{
|
||||
return internal.getBitDepth();
|
||||
}
|
||||
|
||||
const BigInteger getActiveOutputChannels() const
|
||||
{
|
||||
return internal.currentOutputChans;
|
||||
}
|
||||
|
||||
const BigInteger getActiveInputChannels() const
|
||||
{
|
||||
return internal.currentInputChans;
|
||||
}
|
||||
|
||||
int getOutputLatencyInSamples()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getInputLatencyInSamples()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int getOutputLatencyInSamples() { return internal.outputLatency; }
|
||||
int getInputLatencyInSamples() { return internal.inputLatency; }
|
||||
|
||||
void start (AudioIODeviceCallback* callback)
|
||||
{
|
||||
|
|
@ -789,16 +757,6 @@ public:
|
|||
oldCallback->audioDeviceStopped();
|
||||
}
|
||||
|
||||
bool isPlaying()
|
||||
{
|
||||
return isStarted && internal.error.isEmpty();
|
||||
}
|
||||
|
||||
const String getLastError()
|
||||
{
|
||||
return internal.error;
|
||||
}
|
||||
|
||||
String inputId, outputId;
|
||||
|
||||
private:
|
||||
|
|
@ -834,8 +792,8 @@ public:
|
|||
outputNames.clear();
|
||||
outputIds.clear();
|
||||
|
||||
snd_ctl_t* handle;
|
||||
snd_ctl_card_info_t* info;
|
||||
snd_ctl_t* handle = 0;
|
||||
snd_ctl_card_info_t* info = 0;
|
||||
snd_ctl_card_info_alloca (&info);
|
||||
|
||||
int cardNum = -1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue