Browse Source

Added latency estimation for ALSA. Minor tweaks to TemporaryFile and some comments.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
02eb45ddf7
7 changed files with 136 additions and 175 deletions
  1. +58
    -86
      juce_amalgamated.cpp
  2. +10
    -1
      juce_amalgamated.h
  3. +1
    -1
      src/core/juce_StandardHeader.h
  4. +4
    -0
      src/gui/components/keyboard/juce_ModifierKeys.h
  5. +23
    -10
      src/io/files/juce_TemporaryFile.cpp
  6. +5
    -0
      src/io/files/juce_TemporaryFile.h
  7. +35
    -77
      src/native/linux/juce_linux_Audio.cpp

+ 58
- 86
juce_amalgamated.cpp View File

@@ -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_;
}

int getCurrentBufferSizeSamples()
{
return internal.bufferSize;
}

double getCurrentSampleRate()
{
return internal.sampleRate;
}

int getCurrentBitDepth()
{
return internal.getBitDepth();
}

const BigInteger getActiveOutputChannels() const
{
return internal.currentOutputChans;
}
bool isOpen() { return isOpen_; }
bool isPlaying() { return isStarted && internal.error.isEmpty(); }
const String getLastError() { return internal.error; }

const BigInteger getActiveInputChannels() const
{
return internal.currentInputChans;
}
int getCurrentBufferSizeSamples() { return internal.bufferSize; }
double getCurrentSampleRate() { return internal.sampleRate; }
int getCurrentBitDepth() { return internal.getBitDepth(); }

int getOutputLatencyInSamples()
{
return 0;
}
const BigInteger getActiveOutputChannels() const { return internal.currentOutputChans; }
const BigInteger getActiveInputChannels() const { return internal.currentInputChans; }

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;


+ 10
- 1
juce_amalgamated.h View File

@@ -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();



+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -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.


+ 4
- 0
src/gui/components/keyboard/juce_ModifierKeys.h View File

@@ -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();


+ 23
- 10
src/io/files/juce_TemporaryFile.cpp View File

@@ -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;
Thread::sleep (50);
/* 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.
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

+ 5
- 0
src/io/files/juce_TemporaryFile.h View File

@@ -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


+ 35
- 77
src/native/linux/juce_linux_Audio.cpp View File

@@ -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;
}
int getCurrentBitDepth()
{
return internal.getBitDepth();
}
const BigInteger getActiveOutputChannels() const
{
return internal.currentOutputChans;
}
const BigInteger getActiveInputChannels() const
{
return internal.currentInputChans;
}
int getOutputLatencyInSamples()
{
return 0;
}
const BigInteger getActiveOutputChannels() const { return internal.currentOutputChans; }
const BigInteger getActiveInputChannels() const { return internal.currentInputChans; }
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…
Cancel
Save