Browse Source

Update juce

tags/1.9.8
falkTX 7 years ago
parent
commit
03d4e33e65
100 changed files with 882 additions and 276 deletions
  1. +17
    -14
      source/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h
  2. +47
    -32
      source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp
  3. +21
    -3
      source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h
  4. +7
    -2
      source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp
  5. +4
    -2
      source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h
  6. +30
    -11
      source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h
  7. +10
    -5
      source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp
  8. +34
    -1
      source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h
  9. +5
    -0
      source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp
  10. +5
    -0
      source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h
  11. +4
    -2
      source/modules/juce_audio_basics/effects/juce_Decibels.h
  12. +5
    -1
      source/modules/juce_audio_basics/effects/juce_IIRFilter.cpp
  13. +4
    -1
      source/modules/juce_audio_basics/effects/juce_IIRFilter.h
  14. +5
    -0
      source/modules/juce_audio_basics/effects/juce_IIRFilterOld.cpp
  15. +5
    -0
      source/modules/juce_audio_basics/effects/juce_IIRFilterOld.h
  16. +5
    -0
      source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp
  17. +5
    -0
      source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h
  18. +4
    -2
      source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h
  19. +4
    -2
      source/modules/juce_audio_basics/effects/juce_Reverb.h
  20. +0
    -5
      source/modules/juce_audio_basics/juce_audio_basics.cpp
  21. +2
    -6
      source/modules/juce_audio_basics/juce_audio_basics.h
  22. +6
    -1
      source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp
  23. +9
    -6
      source/modules/juce_audio_basics/midi/juce_MidiBuffer.h
  24. +5
    -0
      source/modules/juce_audio_basics/midi/juce_MidiFile.cpp
  25. +4
    -2
      source/modules/juce_audio_basics/midi/juce_MidiFile.h
  26. +5
    -0
      source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp
  27. +4
    -1
      source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h
  28. +5
    -0
      source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp
  29. +4
    -2
      source/modules/juce_audio_basics/midi/juce_MidiMessage.h
  30. +4
    -0
      source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp
  31. +4
    -2
      source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h
  32. +5
    -0
      source/modules/juce_audio_basics/midi/juce_MidiRPN.cpp
  33. +4
    -2
      source/modules/juce_audio_basics/midi/juce_MidiRPN.h
  34. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp
  35. +4
    -2
      source/modules/juce_audio_basics/mpe/juce_MPEInstrument.h
  36. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp
  37. +4
    -2
      source/modules/juce_audio_basics/mpe/juce_MPEMessages.h
  38. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPENote.cpp
  39. +4
    -2
      source/modules/juce_audio_basics/mpe/juce_MPENote.h
  40. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp
  41. +4
    -2
      source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h
  42. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp
  43. +4
    -2
      source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h
  44. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp
  45. +4
    -1
      source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h
  46. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPEValue.cpp
  47. +4
    -2
      source/modules/juce_audio_basics/mpe/juce_MPEValue.h
  48. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPEZone.cpp
  49. +4
    -2
      source/modules/juce_audio_basics/mpe/juce_MPEZone.h
  50. +5
    -0
      source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp
  51. +4
    -2
      source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h
  52. +4
    -1
      source/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h
  53. +4
    -2
      source/modules/juce_audio_basics/sources/juce_AudioSource.h
  54. +5
    -0
      source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp
  55. +4
    -2
      source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h
  56. +5
    -0
      source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp
  57. +4
    -2
      source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h
  58. +5
    -0
      source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp
  59. +4
    -2
      source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h
  60. +5
    -1
      source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp
  61. +4
    -2
      source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h
  62. +5
    -0
      source/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp
  63. +4
    -2
      source/modules/juce_audio_basics/sources/juce_MixerAudioSource.h
  64. +4
    -2
      source/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h
  65. +5
    -0
      source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp
  66. +4
    -2
      source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h
  67. +5
    -0
      source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp
  68. +4
    -2
      source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h
  69. +5
    -0
      source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp
  70. +4
    -2
      source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h
  71. +13
    -8
      source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp
  72. +16
    -8
      source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h
  73. +6
    -1
      source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp
  74. +4
    -2
      source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h
  75. +6
    -0
      source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp
  76. +17
    -1
      source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h
  77. +5
    -0
      source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp
  78. +4
    -2
      source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h
  79. +4
    -2
      source/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h
  80. +8
    -10
      source/modules/juce_audio_devices/juce_audio_devices.cpp
  81. +1
    -6
      source/modules/juce_audio_devices/juce_audio_devices.h
  82. +4
    -1
      source/modules/juce_audio_devices/midi_io/juce_MidiInput.h
  83. +5
    -0
      source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp
  84. +4
    -2
      source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h
  85. +5
    -0
      source/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp
  86. +4
    -2
      source/modules/juce_audio_devices/midi_io/juce_MidiOutput.h
  87. +9
    -7
      source/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h
  88. +24
    -1
      source/modules/juce_audio_devices/native/juce_android_Audio.cpp
  89. +7
    -2
      source/modules/juce_audio_devices/native/juce_android_Midi.cpp
  90. +57
    -21
      source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp
  91. +40
    -4
      source/modules/juce_audio_devices/native/juce_ios_Audio.cpp
  92. +6
    -1
      source/modules/juce_audio_devices/native/juce_ios_Audio.h
  93. +77
    -24
      source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp
  94. +21
    -1
      source/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp
  95. +6
    -1
      source/modules/juce_audio_devices/native/juce_linux_Midi.cpp
  96. +15
    -2
      source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
  97. +5
    -0
      source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp
  98. +15
    -2
      source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp
  99. +31
    -3
      source/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp
  100. +16
    -18
      source/modules/juce_audio_devices/native/juce_win32_Midi.cpp

+ 17
- 14
source/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -46,14 +46,15 @@ public:
/** Frame rate types. */ /** Frame rate types. */
enum FrameRateType enum FrameRateType
{ {
fps24 = 0,
fps25 = 1,
fps2997 = 2,
fps30 = 3,
fps2997drop = 4,
fps30drop = 5,
fps60 = 6,
fps60drop = 7,
fps23976 = 0,
fps24 = 1,
fps25 = 2,
fps2997 = 3,
fps30 = 4,
fps2997drop = 5,
fps30drop = 6,
fps60 = 7,
fps60drop = 8,
fpsUnknown = 99 fpsUnknown = 99
}; };
@@ -70,12 +71,12 @@ public:
/** Time signature denominator, e.g. the 4 of a 3/4 time sig */ /** Time signature denominator, e.g. the 4 of a 3/4 time sig */
int timeSigDenominator; int timeSigDenominator;
/** The current play position, in samples from the start of the edit. */
/** The current play position, in samples from the start of the timeline. */
int64 timeInSamples; int64 timeInSamples;
/** The current play position, in seconds from the start of the edit. */
/** The current play position, in seconds from the start of the timeline. */
double timeInSeconds; double timeInSeconds;
/** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */
/** For timecode, the position of the start of the timeline, in seconds from 00:00:00:00. */
double editOriginTime; double editOriginTime;
/** The current play position, in pulses-per-quarter-note. */ /** The current play position, in pulses-per-quarter-note. */
@@ -83,7 +84,7 @@ public:
/** The position of the start of the last bar, in pulses-per-quarter-note. /** The position of the start of the last bar, in pulses-per-quarter-note.
This is the time from the start of the edit to the start of the current
This is the time from the start of the timeline to the start of the current
bar, in ppq units. bar, in ppq units.
Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If
@@ -150,3 +151,5 @@ public:
/** Rewinds the audio. */ /** Rewinds the audio. */
virtual void transportRewind() {} virtual void transportRewind() {}
}; };
} // namespace juce

+ 47
- 32
source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {} AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {}
AudioChannelSet::AudioChannelSet (const Array<ChannelType>& c) AudioChannelSet::AudioChannelSet (const Array<ChannelType>& c)
{ {
@@ -65,6 +68,8 @@ String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type)
case ambisonicX: return NEEDS_TRANS("Ambisonic X"); case ambisonicX: return NEEDS_TRANS("Ambisonic X");
case ambisonicY: return NEEDS_TRANS("Ambisonic Y"); case ambisonicY: return NEEDS_TRANS("Ambisonic Y");
case ambisonicZ: return NEEDS_TRANS("Ambisonic Z"); case ambisonicZ: return NEEDS_TRANS("Ambisonic Z");
case topSideLeft: return NEEDS_TRANS("Top Side Left");
case topSideRight: return NEEDS_TRANS("Top Side Right");
default: break; default: break;
} }
@@ -105,6 +110,8 @@ String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelT
case ambisonicX: return "X"; case ambisonicX: return "X";
case ambisonicY: return "Y"; case ambisonicY: return "Y";
case ambisonicZ: return "Z"; case ambisonicZ: return "Z";
case topSideLeft: return "Tsl";
case topSideRight: return "Tsr";
default: break; default: break;
} }
@@ -144,6 +151,8 @@ AudioChannelSet::ChannelType AudioChannelSet::getChannelTypeFromAbbreviation (co
if (abbr == "X") return ambisonicX; if (abbr == "X") return ambisonicX;
if (abbr == "Y") return ambisonicY; if (abbr == "Y") return ambisonicY;
if (abbr == "Z") return ambisonicZ; if (abbr == "Z") return ambisonicZ;
if (abbr == "Tsl") return topSideLeft;
if (abbr == "Tsr") return topSideRight;
return unknown; return unknown;
} }
@@ -189,16 +198,18 @@ String AudioChannelSet::getDescription() const
if (*this == createLRS()) return "LRS"; if (*this == createLRS()) return "LRS";
if (*this == createLCRS()) return "LCRS"; if (*this == createLCRS()) return "LCRS";
if (*this == create5point0()) return "5.0 Surround";
if (*this == create5point1()) return "5.1 Surround";
if (*this == create6point0()) return "6.0 Surround";
if (*this == create6point1()) return "6.1 Surround";
if (*this == create6point0Music()) return "6.0 (Music) Surround";
if (*this == create6point1Music()) return "6.1 (Music) Surround";
if (*this == create7point0()) return "7.0 Surround";
if (*this == create7point1()) return "7.1 Surround";
if (*this == create7point0SDDS()) return "7.0 Surround SDDS";
if (*this == create7point1SDDS()) return "7.1 Surround SDDS";
if (*this == create5point0()) return "5.0 Surround";
if (*this == create5point1()) return "5.1 Surround";
if (*this == create6point0()) return "6.0 Surround";
if (*this == create6point1()) return "6.1 Surround";
if (*this == create6point0Music()) return "6.0 (Music) Surround";
if (*this == create6point1Music()) return "6.1 (Music) Surround";
if (*this == create7point0()) return "7.0 Surround";
if (*this == create7point1()) return "7.1 Surround";
if (*this == create7point0SDDS()) return "7.0 Surround SDDS";
if (*this == create7point1SDDS()) return "7.1 Surround SDDS";
if (*this == create7point0point2()) return "7.0.2 Surround";
if (*this == create7point1point2()) return "7.1.2 Surround";
if (*this == quadraphonic()) return "Quadraphonic"; if (*this == quadraphonic()) return "Quadraphonic";
if (*this == pentagonal()) return "Pentagonal"; if (*this == pentagonal()) return "Pentagonal";
@@ -212,7 +223,7 @@ String AudioChannelSet::getDescription() const
bool AudioChannelSet::isDiscreteLayout() const noexcept bool AudioChannelSet::isDiscreteLayout() const noexcept
{ {
for (auto& speaker : getChannelTypes()) for (auto& speaker : getChannelTypes())
if (speaker <= ambisonicZ)
if (speaker <= topSideRight)
return false; return false;
return true; return true;
@@ -272,27 +283,29 @@ void AudioChannelSet::removeChannel (ChannelType newChannel)
channels.clearBit (bit); channels.clearBit (bit);
} }
AudioChannelSet AudioChannelSet::disabled() { return {}; }
AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); }
AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); }
AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); }
AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); }
AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); }
AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); }
AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); }
AudioChannelSet AudioChannelSet::disabled() { return {}; }
AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); }
AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); }
AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); }
AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); }
AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); }
AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); }
AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); }
AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); }
AudioChannelSet AudioChannelSet::create7point1point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); }
AudioChannelSet AudioChannelSet::discreteChannels (int numChannels) AudioChannelSet AudioChannelSet::discreteChannels (int numChannels)
@@ -414,3 +427,5 @@ int32 AudioChannelSet::getWaveChannelMask() const noexcept
return (channels.toInteger() >> 1); return (channels.toInteger() >> 1);
} }
} // namespace juce

+ 21
- 3
source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -194,6 +194,18 @@ public:
*/ */
static AudioChannelSet JUCE_CALLTYPE create7point1SDDS(); static AudioChannelSet JUCE_CALLTYPE create7point1SDDS();
/** Creates a set for Dolby Atmos 7.0.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight).
Is equivalent to: n/a (VST), AAX_eStemFormat_7_0_2 (AAX), n/a (CoreAudio)
*/
static AudioChannelSet JUCE_CALLTYPE create7point0point2();
/** Creates a set for Dolby Atmos 7.1.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE, topSideLeft, topSideRight).
Is equivalent to: k71_2 (VST), AAX_eStemFormat_7_1_2 (AAX), n/a (CoreAudio)
*/
static AudioChannelSet JUCE_CALLTYPE create7point1point2();
//============================================================================== //==============================================================================
/** Creates a set for ambisonic surround setups (ambisonicW, ambisonicX, ambisonicY, ambisonicZ). /** Creates a set for ambisonic surround setups (ambisonicW, ambisonicX, ambisonicY, ambisonicZ).
@@ -289,6 +301,10 @@ public:
ambisonicY = 26, ambisonicY = 26,
ambisonicZ = 27, ambisonicZ = 27,
// Used by Dolby Atmos 7.0.2 and 7.1.2
topSideLeft = 28, // Lts (AAX), Tsl (VST)
topSideRight = 29, // Rts (AAX), Tsr (VST)
discreteChannel0 = 64 /**< Non-typed individual channels are indexed upwards from this value. */ discreteChannel0 = 64 /**< Non-typed individual channels are indexed upwards from this value. */
}; };
@@ -305,7 +321,7 @@ public:
//============================================================================== //==============================================================================
enum enum
{ {
maxChannelsOfNamedLayout = 8
maxChannelsOfNamedLayout = 10
}; };
/** Adds a channel to the set. */ /** Adds a channel to the set. */
@@ -388,3 +404,5 @@ private:
explicit AudioChannelSet (uint32); explicit AudioChannelSet (uint32);
explicit AudioChannelSet (const Array<ChannelType>&); explicit AudioChannelSet (const Array<ChannelType>&);
}; };
} // namespace juce

+ 7
- 2
source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample) void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
{ {
const double maxVal = (double) 0x7fff; const double maxVal = (double) 0x7fff;
@@ -309,7 +312,7 @@ void AudioDataConverters::convertInt24BEToFloat (const void* const source, float
void AudioDataConverters::convertInt32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) void AudioDataConverters::convertInt32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
{ {
const float scale = 1.0f / 0x7fffffff;
const auto scale = 1.0f / (float) 0x7fffffff;
const char* intData = static_cast<const char*> (source); const char* intData = static_cast<const char*> (source);
if (source != (void*) dest || srcBytesPerSample >= 4) if (source != (void*) dest || srcBytesPerSample >= 4)
@@ -334,7 +337,7 @@ void AudioDataConverters::convertInt32LEToFloat (const void* const source, float
void AudioDataConverters::convertInt32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) void AudioDataConverters::convertInt32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
{ {
const float scale = 1.0f / 0x7fffffff;
const auto scale = 1.0f / (float) 0x7fffffff;
const char* intData = static_cast<const char*> (source); const char* intData = static_cast<const char*> (source);
if (source != (void*) dest || srcBytesPerSample >= 4) if (source != (void*) dest || srcBytesPerSample >= 4)
@@ -596,3 +599,5 @@ public:
static AudioConversionTests audioConversionUnitTests; static AudioConversionTests audioConversionUnitTests;
#endif #endif
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -708,3 +708,5 @@ private:
AudioDataConverters(); AudioDataConverters();
JUCE_DECLARE_NON_COPYABLE (AudioDataConverters) JUCE_DECLARE_NON_COPYABLE (AudioDataConverters)
}; };
} // namespace juce

+ 30
- 11
source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -184,11 +184,19 @@ public:
: numChannels (other.numChannels), : numChannels (other.numChannels),
size (other.size), size (other.size),
allocatedBytes (other.allocatedBytes), allocatedBytes (other.allocatedBytes),
channels (other.channels),
allocatedData (static_cast<HeapBlock<char, true>&&> (other.allocatedData)), allocatedData (static_cast<HeapBlock<char, true>&&> (other.allocatedData)),
isClear (other.isClear) isClear (other.isClear)
{ {
memcpy (preallocatedChannelSpace, other.preallocatedChannelSpace, sizeof (preallocatedChannelSpace));
if (numChannels < (int) numElementsInArray (preallocatedChannelSpace))
{
channels = preallocatedChannelSpace;
memcpy (preallocatedChannelSpace, other.channels, sizeof (preallocatedChannelSpace));
}
else
{
channels = other.channels;
}
other.numChannels = 0; other.numChannels = 0;
other.size = 0; other.size = 0;
other.allocatedBytes = 0; other.allocatedBytes = 0;
@@ -200,10 +208,19 @@ public:
numChannels = other.numChannels; numChannels = other.numChannels;
size = other.size; size = other.size;
allocatedBytes = other.allocatedBytes; allocatedBytes = other.allocatedBytes;
channels = other.channels;
allocatedData = static_cast<HeapBlock<char, true>&&> (other.allocatedData); allocatedData = static_cast<HeapBlock<char, true>&&> (other.allocatedData);
isClear = other.isClear; isClear = other.isClear;
memcpy (preallocatedChannelSpace, other.preallocatedChannelSpace, sizeof (preallocatedChannelSpace));
if (numChannels < (int) numElementsInArray (preallocatedChannelSpace))
{
channels = preallocatedChannelSpace;
memcpy (preallocatedChannelSpace, other.channels, sizeof (preallocatedChannelSpace));
}
else
{
channels = other.channels;
}
other.numChannels = 0; other.numChannels = 0;
other.size = 0; other.size = 0;
other.allocatedBytes = 0; other.allocatedBytes = 0;
@@ -332,7 +349,7 @@ public:
auto numSamplesToCopy = (size_t) jmin (newNumSamples, size); auto numSamplesToCopy = (size_t) jmin (newNumSamples, size);
auto newChannels = reinterpret_cast<Type**> (newData.getData());
auto newChannels = reinterpret_cast<Type**> (newData.get());
auto newChan = reinterpret_cast<Type*> (newData + channelListSize); auto newChan = reinterpret_cast<Type*> (newData + channelListSize);
for (int j = 0; j < newNumChannels; ++j) for (int j = 0; j < newNumChannels; ++j)
@@ -364,7 +381,7 @@ public:
{ {
allocatedBytes = newTotalBytes; allocatedBytes = newTotalBytes;
allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear); allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear);
channels = reinterpret_cast<Type**> (allocatedData.getData());
channels = reinterpret_cast<Type**> (allocatedData.get());
} }
auto* chan = reinterpret_cast<Type*> (allocatedData + channelListSize); auto* chan = reinterpret_cast<Type*> (allocatedData + channelListSize);
@@ -629,7 +646,7 @@ public:
jassert (isPositiveAndBelow (channel, numChannels)); jassert (isPositiveAndBelow (channel, numChannels));
jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
const auto increment = (endGain - startGain) / numSamples;
const auto increment = (endGain - startGain) / (float) numSamples;
auto* d = channels[channel] + startSample; auto* d = channels[channel] + startSample;
while (--numSamples >= 0) while (--numSamples >= 0)
@@ -1051,7 +1068,7 @@ private:
auto channelListSize = sizeof (Type*) * (size_t) (numChannels + 1); auto channelListSize = sizeof (Type*) * (size_t) (numChannels + 1);
allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (Type) + channelListSize + 32; allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (Type) + channelListSize + 32;
allocatedData.malloc (allocatedBytes); allocatedData.malloc (allocatedBytes);
channels = reinterpret_cast<Type**> (allocatedData.getData());
channels = reinterpret_cast<Type**> (allocatedData.get());
auto* chan = (Type*) (allocatedData + channelListSize); auto* chan = (Type*) (allocatedData + channelListSize);
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
@@ -1076,7 +1093,7 @@ private:
else else
{ {
allocatedData.malloc ((size_t) numChannels + 1, sizeof (Type*)); allocatedData.malloc ((size_t) numChannels + 1, sizeof (Type*));
channels = reinterpret_cast<Type**> (allocatedData.getData());
channels = reinterpret_cast<Type**> (allocatedData.get());
} }
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
@@ -1105,3 +1122,5 @@ private:
@see AudioBuffer @see AudioBuffer
*/ */
typedef AudioBuffer<float> AudioSampleBuffer; typedef AudioBuffer<float> AudioSampleBuffer;
} // namespace juce

+ 10
- 5
source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace FloatVectorHelpers namespace FloatVectorHelpers
{ {
#define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest)); #define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest));
@@ -874,7 +877,7 @@ void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, cons
vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier), vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier),
JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, ) JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, )
#else #else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier,
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = (float) src[i] * multiplier,
Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 ((const __m128i*) src))), Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 ((const __m128i*) src))),
JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST,
const Mode::ParallelType mult = Mode::load1 (multiplier);) const Mode::ParallelType mult = Mode::load1 (multiplier);)
@@ -1068,9 +1071,9 @@ public:
#else #else
// These tests deliberately operate on misaligned memory and will be flagged up by // These tests deliberately operate on misaligned memory and will be flagged up by
// checks for undefined behavior! // checks for undefined behavior!
ValueType* const data1 = addBytesToPointer (buffer1.getData(), random.nextInt (16));
ValueType* const data2 = addBytesToPointer (buffer2.getData(), random.nextInt (16));
int* const int1 = addBytesToPointer (buffer3.getData(), random.nextInt (16));
ValueType* const data1 = addBytesToPointer (buffer1.get(), random.nextInt (16));
ValueType* const data2 = addBytesToPointer (buffer2.get(), random.nextInt (16));
int* const int1 = addBytesToPointer (buffer3.get(), random.nextInt (16));
#endif #endif
fillRandomly (random, data1, num); fillRandomly (random, data1, num);
@@ -1158,7 +1161,7 @@ public:
static void convertFixed (float* d, const int* s, ValueType multiplier, int num) static void convertFixed (float* d, const int* s, ValueType multiplier, int num)
{ {
while (--num >= 0) while (--num >= 0)
*d++ = *s++ * multiplier;
*d++ = (float) *s++ * multiplier;
} }
static bool areAllValuesEqual (const ValueType* d, int num, ValueType target) static bool areAllValuesEqual (const ValueType* d, int num, ValueType target)
@@ -1200,3 +1203,5 @@ public:
static FloatVectorOperationsTests vectorOpTests; static FloatVectorOperationsTests vectorOpTests;
#endif #endif
} // namespace juce

+ 34
- 1
source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
#if JUCE_INTEL #if JUCE_INTEL
#define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0; #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0;
@@ -219,3 +220,35 @@ public:
*/ */
static void JUCE_CALLTYPE disableDenormalisedNumberSupport() noexcept; static void JUCE_CALLTYPE disableDenormalisedNumberSupport() noexcept;
}; };
//==============================================================================
/**
Helper class providing an RAII-based mechanism for temporarily disabling
denormals on your CPU.
*/
class ScopedNoDenormals
{
public:
inline ScopedNoDenormals() noexcept
{
#if JUCE_USE_SSE_INTRINSICS
mxcsr = _mm_getcsr();
_mm_setcsr (mxcsr | 0x8040); // add the DAZ and FZ bits
#endif
}
inline ~ScopedNoDenormals() noexcept
{
#if JUCE_USE_SSE_INTRINSICS
_mm_setcsr (mxcsr);
#endif
}
private:
#if JUCE_USE_SSE_INTRINSICS
unsigned int mxcsr;
#endif
};
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
struct CatmullRomAlgorithm struct CatmullRomAlgorithm
{ {
static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept
@@ -58,3 +61,5 @@ int CatmullRomInterpolator::processAdding (double actualRatio, const float* in,
{ {
return interpolateAdding<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); return interpolateAdding<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain);
} }
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
/** /**
Interpolator for resampling a stream of floats using Catmull-Rom interpolation. Interpolator for resampling a stream of floats using Catmull-Rom interpolation.
@@ -84,3 +87,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator)
}; };
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/effects/juce_Decibels.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -96,3 +96,5 @@ private:
Decibels(); // This class can't be instantiated, it's just a holder for static methods.. Decibels(); // This class can't be instantiated, it's just a holder for static methods..
JUCE_DECLARE_NON_COPYABLE (Decibels) JUCE_DECLARE_NON_COPYABLE (Decibels)
}; };
} // namespace juce

+ 5
- 1
source/modules/juce_audio_basics/effects/juce_IIRFilter.cpp View File

@@ -20,7 +20,9 @@
============================================================================== ==============================================================================
*/ */
//==============================================================================
namespace juce
{
IIRCoefficients::IIRCoefficients() noexcept IIRCoefficients::IIRCoefficients() noexcept
{ {
zeromem (coefficients, sizeof (coefficients)); zeromem (coefficients, sizeof (coefficients));
@@ -335,3 +337,5 @@ void IIRFilter::processSamples (float* const samples, const int numSamples) noex
} }
#undef JUCE_SNAP_TO_ZERO #undef JUCE_SNAP_TO_ZERO
} // namespace juce

+ 4
- 1
source/modules/juce_audio_basics/effects/juce_IIRFilter.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
class IIRFilter; class IIRFilter;
@@ -205,3 +206,5 @@ protected:
IIRFilter& operator= (const IIRFilter&); IIRFilter& operator= (const IIRFilter&);
JUCE_LEAK_DETECTOR (IIRFilter) JUCE_LEAK_DETECTOR (IIRFilter)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/effects/juce_IIRFilterOld.cpp View File

@@ -28,6 +28,9 @@
#define JUCE_SNAP_TO_ZERO(n) #define JUCE_SNAP_TO_ZERO(n)
#endif #endif
namespace juce
{
//============================================================================== //==============================================================================
IIRFilterOld::IIRFilterOld() IIRFilterOld::IIRFilterOld()
: active (false), v1 (0), v2 (0) : active (false), v1 (0), v2 (0)
@@ -237,3 +240,5 @@ void IIRFilterOld::setCoefficients (double c1, double c2, double c3,
} }
#undef JUCE_SNAP_TO_ZERO #undef JUCE_SNAP_TO_ZERO
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/effects/juce_IIRFilterOld.h View File

@@ -26,6 +26,9 @@
#define __JUCE_IIRFILTER_OLD_JUCEHEADER__ #define __JUCE_IIRFILTER_OLD_JUCEHEADER__
namespace juce
{
//============================================================================== //==============================================================================
/** /**
An IIR filter that can perform low, high, or band-pass filtering on an An IIR filter that can perform low, high, or band-pass filtering on an
@@ -145,4 +148,6 @@ protected:
}; };
} // namespace juce
#endif // __JUCE_IIRFILTER_OLD_JUCEHEADER__ #endif // __JUCE_IIRFILTER_OLD_JUCEHEADER__

+ 5
- 0
source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace namespace
{ {
static forcedinline void pushInterpolationSample (float* lastInputSamples, const float newValue) noexcept static forcedinline void pushInterpolationSample (float* lastInputSamples, const float newValue) noexcept
@@ -196,3 +199,5 @@ int LagrangeInterpolator::processAdding (double actualRatio, const float* in, fl
{ {
return interpolateAdding<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); return interpolateAdding<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain);
} }
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
/** /**
Interpolator for resampling a stream of floats using 4-point lagrange interpolation. Interpolator for resampling a stream of floats using 4-point lagrange interpolation.
@@ -84,3 +87,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator)
}; };
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -182,3 +182,5 @@ private:
FloatType currentValue = 0, target = 0, step = 0; FloatType currentValue = 0, target = 0, step = 0;
int countdown = 0, stepsToTarget = 0; int countdown = 0, stepsToTarget = 0;
}; };
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/effects/juce_Reverb.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -316,3 +316,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb)
}; };
} // namespace juce

+ 0
- 5
source/modules/juce_audio_basics/juce_audio_basics.cpp View File

@@ -76,9 +76,6 @@
#include <arm_neon.h> #include <arm_neon.h>
#endif #endif
namespace juce
{
#include "buffers/juce_AudioDataConverters.cpp" #include "buffers/juce_AudioDataConverters.cpp"
#include "buffers/juce_FloatVectorOperations.cpp" #include "buffers/juce_FloatVectorOperations.cpp"
#include "buffers/juce_AudioChannelSet.cpp" #include "buffers/juce_AudioChannelSet.cpp"
@@ -110,5 +107,3 @@ namespace juce
#include "sources/juce_ReverbAudioSource.cpp" #include "sources/juce_ReverbAudioSource.cpp"
#include "sources/juce_ToneGeneratorAudioSource.cpp" #include "sources/juce_ToneGeneratorAudioSource.cpp"
#include "synthesisers/juce_Synthesiser.cpp" #include "synthesisers/juce_Synthesiser.cpp"
}

+ 2
- 6
source/modules/juce_audio_basics/juce_audio_basics.h View File

@@ -31,7 +31,7 @@
ID: juce_audio_basics ID: juce_audio_basics
vendor: juce vendor: juce
version: 5.1.1
version: 5.1.2
name: JUCE audio and MIDI data classes name: JUCE audio and MIDI data classes
description: Classes for audio buffer manipulation, midi message handling, synthesis, etc. description: Classes for audio buffer manipulation, midi message handling, synthesis, etc.
website: http://www.juce.com/juce website: http://www.juce.com/juce
@@ -51,9 +51,7 @@
#include <juce_core/juce_core.h> #include <juce_core/juce_core.h>
namespace juce
{
//==============================================================================
#undef Complex // apparently some C libraries actually define these symbols (!) #undef Complex // apparently some C libraries actually define these symbols (!)
#undef Factor #undef Factor
@@ -95,5 +93,3 @@ namespace juce
#include "sources/juce_ToneGeneratorAudioSource.h" #include "sources/juce_ToneGeneratorAudioSource.h"
#include "synthesisers/juce_Synthesiser.h" #include "synthesisers/juce_Synthesiser.h"
#include "audio_play_head/juce_AudioPlayHead.h" #include "audio_play_head/juce_AudioPlayHead.h"
}

+ 6
- 1
source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace MidiBufferHelpers namespace MidiBufferHelpers
{ {
inline int getEventTime (const void* const d) noexcept inline int getEventTime (const void* const d) noexcept
@@ -34,7 +37,7 @@ namespace MidiBufferHelpers
inline uint16 getEventTotalSize (const void* const d) noexcept inline uint16 getEventTotalSize (const void* const d) noexcept
{ {
return getEventDataSize (d) + sizeof (int32) + sizeof (uint16);
return (uint16) (getEventDataSize (d) + sizeof (int32) + sizeof (uint16));
} }
static int findActualEventLength (const uint8* const data, const int maxBytes) noexcept static int findActualEventLength (const uint8* const data, const int maxBytes) noexcept
@@ -225,3 +228,5 @@ bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePositio
return true; return true;
} }
} // namespace juce

+ 9
- 6
source/modules/juce_audio_basics/midi/juce_MidiBuffer.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -160,8 +160,8 @@ public:
/** /**
Used to iterate through the events in a MidiBuffer. Used to iterate through the events in a MidiBuffer.
Note that altering the buffer while an iterator is using it isn't a
safe operation.
Note that altering the buffer while an iterator is using it will produce
undefined behaviour.
@see MidiBuffer @see MidiBuffer
*/ */
@@ -172,6 +172,9 @@ public:
/** Creates an Iterator for this MidiBuffer. */ /** Creates an Iterator for this MidiBuffer. */
Iterator (const MidiBuffer&) noexcept; Iterator (const MidiBuffer&) noexcept;
/** Creates a copy of an iterator. */
Iterator (const Iterator&) noexcept = default;
/** Destructor. */ /** Destructor. */
~Iterator() noexcept; ~Iterator() noexcept;
@@ -214,8 +217,6 @@ public:
//============================================================================== //==============================================================================
const MidiBuffer& buffer; const MidiBuffer& buffer;
const uint8* data; const uint8* data;
JUCE_DECLARE_NON_COPYABLE (Iterator)
}; };
/** The raw data holding this buffer. /** The raw data holding this buffer.
@@ -227,3 +228,5 @@ public:
private: private:
JUCE_LEAK_DETECTOR (MidiBuffer) JUCE_LEAK_DETECTOR (MidiBuffer)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/midi/juce_MidiFile.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace MidiFileHelpers namespace MidiFileHelpers
{ {
static void writeVariableLengthInt (OutputStream& out, unsigned int v) static void writeVariableLengthInt (OutputStream& out, unsigned int v)
@@ -443,3 +446,5 @@ bool MidiFile::writeTrack (OutputStream& mainOut, const int trackNum)
return true; return true;
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/midi/juce_MidiFile.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -178,3 +178,5 @@ private:
JUCE_LEAK_DETECTOR (MidiFile) JUCE_LEAK_DETECTOR (MidiFile)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MidiKeyboardState::MidiKeyboardState() MidiKeyboardState::MidiKeyboardState()
{ {
zerostruct (noteStates); zerostruct (noteStates);
@@ -179,3 +182,5 @@ void MidiKeyboardState::removeListener (MidiKeyboardStateListener* const listene
const ScopedLock sl (lock); const ScopedLock sl (lock);
listeners.removeFirstMatchingValue (listener); listeners.removeFirstMatchingValue (listener);
} }
} // namespace juce

+ 4
- 1
source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
class MidiKeyboardState; class MidiKeyboardState;
@@ -197,3 +198,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace MidiHelpers namespace MidiHelpers
{ {
inline uint8 initialByte (const int type, const int channel) noexcept inline uint8 initialByte (const int type, const int channel) noexcept
@@ -1119,3 +1122,5 @@ const char* MidiMessage::getControllerName (const int n)
return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] : nullptr; return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] : nullptr;
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/midi/juce_MidiMessage.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -936,3 +936,5 @@ private:
inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : (uint8*) packedData.asBytes; } inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : (uint8*) packedData.asBytes; }
uint8* allocateSpace (int); uint8* allocateSpace (int);
}; };
} // namespace juce

+ 4
- 0
source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp View File

@@ -20,6 +20,8 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) : message (mm) {} MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) : message (mm) {}
MidiMessageSequence::MidiEventHolder::MidiEventHolder (MidiMessage&& mm) : message (static_cast<MidiMessage&&> (mm)) {} MidiMessageSequence::MidiEventHolder::MidiEventHolder (MidiMessage&& mm) : message (static_cast<MidiMessage&&> (mm)) {}
@@ -334,3 +336,5 @@ void MidiMessageSequence::createControllerUpdatesForTime (int channelNumber, dou
} }
} }
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -294,3 +294,5 @@ private:
JUCE_LEAK_DETECTOR (MidiMessageSequence) JUCE_LEAK_DETECTOR (MidiMessageSequence)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/midi/juce_MidiRPN.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MidiRPNDetector::MidiRPNDetector() noexcept MidiRPNDetector::MidiRPNDetector() noexcept
{ {
} }
@@ -369,3 +372,5 @@ private:
static MidiRPNGeneratorTests MidiRPNGeneratorUnitTests; static MidiRPNGeneratorTests MidiRPNGeneratorUnitTests;
#endif // JUCE_UNIT_TESTS #endif // JUCE_UNIT_TESTS
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/midi/juce_MidiRPN.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** Represents a MIDI RPN (registered parameter number) or NRPN (non-registered /** Represents a MIDI RPN (registered parameter number) or NRPN (non-registered
@@ -144,3 +144,5 @@ public:
bool isNRPN = false, bool isNRPN = false,
bool use14BitValue = true); bool use14BitValue = true);
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace namespace
{ {
const uint8 noLSBValueReceived = 0xff; const uint8 noLSBValueReceived = 0xff;
@@ -2148,3 +2151,5 @@ private:
static MPEInstrumentTests MPEInstrumentUnitTests; static MPEInstrumentTests MPEInstrumentUnitTests;
#endif // JUCE_UNIT_TESTS #endif // JUCE_UNIT_TESTS
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/mpe/juce_MPEInstrument.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/* /*
@@ -374,3 +374,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPEInstrument) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPEInstrument)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MidiBuffer MPEMessages::addZone (MPEZone zone) MidiBuffer MPEMessages::addZone (MPEZone zone)
{ {
MidiBuffer buffer (MidiRPNGenerator::generate (zone.getFirstNoteChannel(), MidiBuffer buffer (MidiRPNGenerator::generate (zone.getFirstNoteChannel(),
@@ -193,3 +196,5 @@ private:
static MPEMessagesTests MPEMessagesUnitTests; static MPEMessagesTests MPEMessagesUnitTests;
#endif // JUCE_UNIT_TESTS #endif // JUCE_UNIT_TESTS
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/mpe/juce_MPEMessages.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -87,3 +87,5 @@ public:
*/ */
static const int zoneLayoutMessagesRpnNumber = 6; static const int zoneLayoutMessagesRpnNumber = 6;
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPENote.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace namespace
{ {
uint16 generateNoteID (int midiChannel, int midiNoteNumber) noexcept uint16 generateNoteID (int midiChannel, int midiNoteNumber) noexcept
@@ -128,3 +131,5 @@ private:
static MPENoteTests MPENoteUnitTests; static MPENoteTests MPENoteUnitTests;
#endif // JUCE_UNIT_TESTS #endif // JUCE_UNIT_TESTS
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/mpe/juce_MPENote.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -172,3 +172,5 @@ struct JUCE_API MPENote
/** Returns true if two notes are different notes, determined by their unique ID. */ /** Returns true if two notes are different notes, determined by their unique ID. */
bool operator!= (const MPENote& other) const noexcept; bool operator!= (const MPENote& other) const noexcept;
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MPESynthesiser::MPESynthesiser() MPESynthesiser::MPESynthesiser()
{ {
} }
@@ -352,3 +355,5 @@ void MPESynthesiser::renderNextSubBlock (AudioBuffer<double>& buffer, int startS
voice->renderNextBlock (buffer, startSample, numSamples); voice->renderNextBlock (buffer, startSample, numSamples);
} }
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -305,3 +305,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiser) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiser)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MPESynthesiserBase::MPESynthesiserBase() MPESynthesiserBase::MPESynthesiserBase()
: instrument (new MPEInstrument), : instrument (new MPEInstrument),
sampleRate (0), sampleRate (0),
@@ -178,3 +181,5 @@ void MPESynthesiserBase::setMinimumRenderingSubdivisionSize (int numSamples, boo
minimumSubBlockSize = numSamples; minimumSubBlockSize = numSamples;
subBlockSubdivisionIsStrict = shouldBeStrict; subBlockSubdivisionIsStrict = shouldBeStrict;
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -204,3 +204,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserBase) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserBase)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MPESynthesiserVoice::MPESynthesiserVoice() MPESynthesiserVoice::MPESynthesiserVoice()
: currentSampleRate (0), noteStartTime (0) : currentSampleRate (0), noteStartTime (0)
{ {
@@ -49,3 +52,5 @@ void MPESynthesiserVoice::clearCurrentNote() noexcept
{ {
currentlyPlayingNote = MPENote(); currentlyPlayingNote = MPENote();
} }
} // namespace juce

+ 4
- 1
source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -183,3 +184,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserVoice) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserVoice)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPEValue.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MPEValue::MPEValue() noexcept : normalisedValue (8192) MPEValue::MPEValue() noexcept : normalisedValue (8192)
{ {
} }
@@ -166,3 +169,5 @@ private:
static MPEValueTests MPEValueUnitTests; static MPEValueTests MPEValueUnitTests;
#endif // JUCE_UNIT_TESTS #endif // JUCE_UNIT_TESTS
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/mpe/juce_MPEValue.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -88,3 +88,5 @@ private:
MPEValue (int normalisedValue); MPEValue (int normalisedValue);
int normalisedValue; int normalisedValue;
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPEZone.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace namespace
{ {
void checkAndLimitZoneParameters (int minValue, void checkAndLimitZoneParameters (int minValue,
@@ -312,3 +315,5 @@ private:
static MPEZoneTests MPEZoneUnitTests; static MPEZoneTests MPEZoneUnitTests;
#endif // JUCE_UNIT_TESTS #endif // JUCE_UNIT_TESTS
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/mpe/juce_MPEZone.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -138,3 +138,5 @@ private:
int perNotePitchbendRange; int perNotePitchbendRange;
int masterPitchbendRange; int masterPitchbendRange;
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MPEZoneLayout::MPEZoneLayout() noexcept MPEZoneLayout::MPEZoneLayout() noexcept
{ {
} }
@@ -378,3 +381,5 @@ static MPEZoneLayoutTests MPEZoneLayoutUnitTests;
#endif // JUCE_UNIT_TESTS #endif // JUCE_UNIT_TESTS
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -157,3 +157,5 @@ private:
void processZoneLayoutRpnMessage (MidiRPNMessage); void processZoneLayoutRpnMessage (MidiRPNMessage);
void processPitchbendRangeRpnMessage (MidiRPNMessage); void processPitchbendRangeRpnMessage (MidiRPNMessage);
}; };
} // namespace juce

+ 4
- 1
source/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
#if JUCE_MAC || JUCE_IOS #if JUCE_MAC || JUCE_IOS
@@ -304,3 +305,5 @@ private:
}; };
#endif #endif
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_AudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -173,3 +173,5 @@ public:
*/ */
virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0; virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0;
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s, BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s,
TimeSliceThread& thread, TimeSliceThread& thread,
const bool deleteSourceWhenDeleted, const bool deleteSourceWhenDeleted,
@@ -307,3 +310,5 @@ int BufferingAudioSource::useTimeSlice()
{ {
return readNextBufferChunk() ? 1 : 100; return readNextBufferChunk() ? 1 : 100;
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -113,3 +113,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioSource) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioSource)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_, ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_,
const bool deleteSourceWhenDeleted) const bool deleteSourceWhenDeleted)
: source (source_, deleteSourceWhenDeleted), : source (source_, deleteSourceWhenDeleted),
@@ -180,3 +183,5 @@ void ChannelRemappingAudioSource::restoreFromXml (const XmlElement& e)
remappedOutputs.add (outs[i].getIntValue()); remappedOutputs.add (outs[i].getIntValue());
} }
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -135,3 +135,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChannelRemappingAudioSource) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChannelRemappingAudioSource)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
IIRFilterAudioSource::IIRFilterAudioSource (AudioSource* const inputSource, IIRFilterAudioSource::IIRFilterAudioSource (AudioSource* const inputSource,
const bool deleteInputWhenDeleted) const bool deleteInputWhenDeleted)
: input (inputSource, deleteInputWhenDeleted) : input (inputSource, deleteInputWhenDeleted)
@@ -73,3 +76,5 @@ void IIRFilterAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& buff
->processSamples (bufferToFill.buffer->getWritePointer (i, bufferToFill.startSample), ->processSamples (bufferToFill.buffer->getWritePointer (i, bufferToFill.startSample),
bufferToFill.numSamples); bufferToFill.numSamples);
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -62,3 +62,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IIRFilterAudioSource) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IIRFilterAudioSource)
}; };
} // namespace juce

+ 5
- 1
source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp View File

@@ -20,7 +20,9 @@
============================================================================== ==============================================================================
*/ */
//==============================================================================
namespace juce
{
MemoryAudioSource::MemoryAudioSource (AudioBuffer<float>& bufferToUse, bool copyMemory, bool shouldLoop) MemoryAudioSource::MemoryAudioSource (AudioBuffer<float>& bufferToUse, bool copyMemory, bool shouldLoop)
: isLooping (shouldLoop) : isLooping (shouldLoop)
{ {
@@ -64,3 +66,5 @@ void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT
if (pos < m) if (pos < m)
dst.clear (bufferToFill.startSample + pos, m - pos); dst.clear (bufferToFill.startSample + pos, m - pos);
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -59,3 +59,5 @@ private:
//============================================================================== //==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryAudioSource) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryAudioSource)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MixerAudioSource::MixerAudioSource() MixerAudioSource::MixerAudioSource()
: currentSampleRate (0.0), bufferSizeExpected (0) : currentSampleRate (0.0), bufferSizeExpected (0)
{ {
@@ -151,3 +154,5 @@ void MixerAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
info.clearActiveBufferRegion(); info.clearActiveBufferRegion();
} }
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_MixerAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -93,3 +93,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MixerAudioSource) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MixerAudioSource)
}; };
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -70,3 +70,5 @@ public:
/** Tells the source whether you'd like it to play in a loop. */ /** Tells the source whether you'd like it to play in a loop. */
virtual void setLooping (bool shouldLoop) { ignoreUnused (shouldLoop); } virtual void setLooping (bool shouldLoop) { ignoreUnused (shouldLoop); }
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource, ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource,
const bool deleteInputWhenDeleted, const bool deleteInputWhenDeleted,
const int channels) const int channels)
@@ -259,3 +262,5 @@ void ResamplingAudioSource::applyFilter (float* samples, int num, FilterState& f
*samples++ = (float) out; *samples++ = (float) out;
} }
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -99,3 +99,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResamplingAudioSource) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResamplingAudioSource)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
ReverbAudioSource::ReverbAudioSource (AudioSource* const inputSource, const bool deleteInputWhenDeleted) ReverbAudioSource::ReverbAudioSource (AudioSource* const inputSource, const bool deleteInputWhenDeleted)
: input (inputSource, deleteInputWhenDeleted), : input (inputSource, deleteInputWhenDeleted),
bypass (false) bypass (false)
@@ -76,3 +79,5 @@ void ReverbAudioSource::setBypassed (bool b) noexcept
reverb.reset(); reverb.reset();
} }
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -68,3 +68,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ReverbAudioSource) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ReverbAudioSource)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
ToneGeneratorAudioSource::ToneGeneratorAudioSource() ToneGeneratorAudioSource::ToneGeneratorAudioSource()
: frequency (1000.0), : frequency (1000.0),
sampleRate (44100.0), sampleRate (44100.0),
@@ -71,3 +74,5 @@ void ToneGeneratorAudioSource::getNextAudioBlock (const AudioSourceChannelInfo&
info.buffer->setSample (j, info.startSample + i, sample); info.buffer->setSample (j, info.startSample + i, sample);
} }
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -65,3 +65,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToneGeneratorAudioSource) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToneGeneratorAudioSource)
}; };
} // namespace juce

+ 13
- 8
source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
SynthesiserSound::SynthesiserSound() {} SynthesiserSound::SynthesiserSound() {}
SynthesiserSound::~SynthesiserSound() {} SynthesiserSound::~SynthesiserSound() {}
@@ -305,8 +308,8 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
voice->noteOnTime = ++lastNoteOnCounter; voice->noteOnTime = ++lastNoteOnCounter;
voice->currentlyPlayingSound = sound; voice->currentlyPlayingSound = sound;
voice->setKeyDown (true); voice->setKeyDown (true);
voice->sostenutoPedalDown = false;
voice->sustainPedalDown = sustainPedalsDown[midiChannel];
voice->setSostenutoPedalDown (false);
voice->setSustainPedalDown (sustainPedalsDown[midiChannel]);
voice->startNote (midiNoteNumber, velocity, sound, voice->startNote (midiNoteNumber, velocity, sound,
lastPitchWheelValues [midiChannel - 1]); lastPitchWheelValues [midiChannel - 1]);
@@ -340,11 +343,11 @@ void Synthesiser::noteOff (const int midiChannel,
if (sound->appliesToNote (midiNoteNumber) if (sound->appliesToNote (midiNoteNumber)
&& sound->appliesToChannel (midiChannel)) && sound->appliesToChannel (midiChannel))
{ {
jassert (! voice->keyIsDown || voice->sustainPedalDown == sustainPedalsDown [midiChannel]);
jassert (! voice->keyIsDown || voice->isSustainPedalDown() == sustainPedalsDown [midiChannel]);
voice->setKeyDown (false); voice->setKeyDown (false);
if (! (voice->sustainPedalDown || voice->sostenutoPedalDown))
if (! (voice->isSustainPedalDown() || voice->isSostenutoPedalDown()))
stopVoice (voice, velocity, allowTailOff); stopVoice (voice, velocity, allowTailOff);
} }
} }
@@ -421,7 +424,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
for (auto* voice : voices) for (auto* voice : voices)
if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown()) if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown())
voice->sustainPedalDown = true;
voice->setSustainPedalDown (true);
} }
else else
{ {
@@ -429,7 +432,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
{ {
if (voice->isPlayingChannel (midiChannel)) if (voice->isPlayingChannel (midiChannel))
{ {
voice->sustainPedalDown = false;
voice->setSustainPedalDown (false);
if (! (voice->isKeyDown() || voice->isSostenutoPedalDown())) if (! (voice->isKeyDown() || voice->isSostenutoPedalDown()))
stopVoice (voice, 1.0f, true); stopVoice (voice, 1.0f, true);
@@ -450,8 +453,8 @@ void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown)
if (voice->isPlayingChannel (midiChannel)) if (voice->isPlayingChannel (midiChannel))
{ {
if (isDown) if (isDown)
voice->sostenutoPedalDown = true;
else if (voice->sostenutoPedalDown)
voice->setSostenutoPedalDown (true);
else if (voice->isSostenutoPedalDown())
stopVoice (voice, 1.0f, true); stopVoice (voice, 1.0f, true);
} }
} }
@@ -567,3 +570,5 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
return low; return low;
} }
} // namespace juce

+ 16
- 8
source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -224,9 +224,15 @@ public:
/** Returns true if the sustain pedal is currently active for this voice. */ /** Returns true if the sustain pedal is currently active for this voice. */
bool isSustainPedalDown() const noexcept { return sustainPedalDown; } bool isSustainPedalDown() const noexcept { return sustainPedalDown; }
/** Modifies the sustain pedal flag. */
void setSustainPedalDown (bool isNowDown) noexcept { sustainPedalDown = isNowDown; }
/** Returns true if the sostenuto pedal is currently active for this voice. */ /** Returns true if the sostenuto pedal is currently active for this voice. */
bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; } bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; }
/** Modifies the sostenuto pedal flag. */
void setSostenutoPedalDown (bool isNowDown) noexcept { sostenutoPedalDown = isNowDown; }
/** Returns true if a voice is sounding in its release phase **/ /** Returns true if a voice is sounding in its release phase **/
bool isPlayingButReleased() const noexcept bool isPlayingButReleased() const noexcept
{ {
@@ -514,15 +520,15 @@ public:
with timestamps outside the specified region will be ignored. with timestamps outside the specified region will be ignored.
*/ */
inline void renderNextBlock (AudioBuffer<float>& outputAudio, inline void renderNextBlock (AudioBuffer<float>& outputAudio,
const MidiBuffer& inputMidi,
int startSample,
int numSamples)
const MidiBuffer& inputMidi,
int startSample,
int numSamples)
{ processNextBlock (outputAudio, inputMidi, startSample, numSamples); } { processNextBlock (outputAudio, inputMidi, startSample, numSamples); }
inline void renderNextBlock (AudioBuffer<double>& outputAudio, inline void renderNextBlock (AudioBuffer<double>& outputAudio,
const MidiBuffer& inputMidi,
int startSample,
int numSamples)
const MidiBuffer& inputMidi,
int startSample,
int numSamples)
{ processNextBlock (outputAudio, inputMidi, startSample, numSamples); } { processNextBlock (outputAudio, inputMidi, startSample, numSamples); }
/** Returns the current target sample rate at which rendering is being done. /** Returns the current target sample rate at which rendering is being done.
@@ -639,3 +645,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser)
}; };
} // namespace juce

+ 6
- 1
source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup() AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup()
: sampleRate (0), : sampleRate (0),
bufferSize (0), bufferSize (0),
@@ -929,7 +932,7 @@ void AudioDeviceManager::LevelMeter::updateLevel (const float* const* channelDat
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
s += std::abs (channelData[i][j]); s += std::abs (channelData[i][j]);
s /= numChannels;
s /= (float) numChannels;
const double decayFactor = 0.99992; const double decayFactor = 0.99992;
@@ -1000,3 +1003,5 @@ double AudioDeviceManager::getCurrentOutputLevel() const noexcept { return out
void AudioDeviceManager::enableInputLevelMeasurement (bool enable) noexcept { inputLevelMeter.setEnabled (enable); } void AudioDeviceManager::enableInputLevelMeasurement (bool enable) noexcept { inputLevelMeter.setEnabled (enable); }
void AudioDeviceManager::enableOutputLevelMeasurement (bool enable) noexcept { outputLevelMeter.setEnabled (enable); } void AudioDeviceManager::enableOutputLevelMeasurement (bool enable) noexcept { outputLevelMeter.setEnabled (enable); }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -518,3 +518,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceManager) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceManager)
}; };
} // namespace juce

+ 6
- 0
source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
AudioIODevice::AudioIODevice (const String& deviceName, const String& deviceTypeName) AudioIODevice::AudioIODevice (const String& deviceName, const String& deviceTypeName)
: name (deviceName), typeName (deviceTypeName) : name (deviceName), typeName (deviceTypeName)
{ {
@@ -30,6 +33,7 @@ AudioIODevice::~AudioIODevice() {}
void AudioIODeviceCallback::audioDeviceError (const String&) {} void AudioIODeviceCallback::audioDeviceError (const String&) {}
bool AudioIODevice::setAudioPreprocessingEnabled (bool) { return false; } bool AudioIODevice::setAudioPreprocessingEnabled (bool) { return false; }
bool AudioIODevice::hasControlPanel() const { return false; } bool AudioIODevice::hasControlPanel() const { return false; }
int AudioIODevice::getXRunCount() const noexcept { return -1; }
bool AudioIODevice::showControlPanel() bool AudioIODevice::showControlPanel()
{ {
@@ -37,3 +41,5 @@ bool AudioIODevice::showControlPanel()
// their hasControlPanel() method. // their hasControlPanel() method.
return false; return false;
} }
} // namespace juce

+ 17
- 1
source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
class AudioIODevice; class AudioIODevice;
@@ -292,6 +293,19 @@ public:
*/ */
virtual bool setAudioPreprocessingEnabled (bool shouldBeEnabled); virtual bool setAudioPreprocessingEnabled (bool shouldBeEnabled);
//==============================================================================
/** Returns the number of under- or over runs reported by the OS since
playback/recording has started.
This number may be different than determining the Xrun count manually (by
measuring the time spent in the audio callback) as the OS may be doing
some buffering internally - especially on mobile devices.
Returns -1 if playback/recording has not started yet or if getting the underrun
count is not supported for this device (Android SDK 23 and lower).
*/
virtual int getXRunCount() const noexcept;
//============================================================================== //==============================================================================
protected: protected:
/** Creates a device, setting its name and type member variables. */ /** Creates a device, setting its name and type member variables. */
@@ -301,3 +315,5 @@ protected:
/** @internal */ /** @internal */
String name, typeName; String name, typeName;
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
AudioIODeviceType::AudioIODeviceType (const String& name) AudioIODeviceType::AudioIODeviceType (const String& name)
: typeName (name) : typeName (name)
{ {
@@ -74,3 +77,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android()
#if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES) #if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES)
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; } AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; }
#endif #endif
} // namespace juce

+ 4
- 2
source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -174,3 +174,5 @@ private:
JUCE_DECLARE_NON_COPYABLE (AudioIODeviceType) JUCE_DECLARE_NON_COPYABLE (AudioIODeviceType)
}; };
} // namespace juce

+ 4
- 2
source/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -53,3 +53,5 @@ private:
SystemAudioVolume(); // Don't instantiate this class, just call its static fns. SystemAudioVolume(); // Don't instantiate this class, just call its static fns.
JUCE_DECLARE_NON_COPYABLE (SystemAudioVolume) JUCE_DECLARE_NON_COPYABLE (SystemAudioVolume)
}; };
} // namespace juce

+ 8
- 10
source/modules/juce_audio_devices/juce_audio_devices.cpp View File

@@ -155,9 +155,6 @@
#endif #endif
namespace juce
{
#include "audio_io/juce_AudioDeviceManager.cpp" #include "audio_io/juce_AudioDeviceManager.cpp"
#include "audio_io/juce_AudioIODevice.cpp" #include "audio_io/juce_AudioIODevice.cpp"
#include "audio_io/juce_AudioIODeviceType.cpp" #include "audio_io/juce_AudioIODeviceType.cpp"
@@ -214,14 +211,15 @@ namespace juce
#if JUCE_USE_ANDROID_OPENSLES #if JUCE_USE_ANDROID_OPENSLES
#include "native/juce_android_OpenSL.cpp" #include "native/juce_android_OpenSL.cpp"
#endif #endif
#endif #endif
#if ! JUCE_SYSTEMAUDIOVOL_IMPLEMENTED #if ! JUCE_SYSTEMAUDIOVOL_IMPLEMENTED
// None of these methods are available. (On Windows you might need to enable WASAPI for this)
float JUCE_CALLTYPE SystemAudioVolume::getGain() { jassertfalse; return 0.0f; }
bool JUCE_CALLTYPE SystemAudioVolume::setGain (float) { jassertfalse; return false; }
bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { jassertfalse; return false; }
bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool) { jassertfalse; return false; }
#endif
namespace juce
{
// None of these methods are available. (On Windows you might need to enable WASAPI for this)
float JUCE_CALLTYPE SystemAudioVolume::getGain() { jassertfalse; return 0.0f; }
bool JUCE_CALLTYPE SystemAudioVolume::setGain (float) { jassertfalse; return false; }
bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { jassertfalse; return false; }
bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool) { jassertfalse; return false; }
} }
#endif

+ 1
- 6
source/modules/juce_audio_devices/juce_audio_devices.h View File

@@ -31,7 +31,7 @@
ID: juce_audio_devices ID: juce_audio_devices
vendor: juce vendor: juce
version: 5.1.1
version: 5.1.2
name: JUCE audio and MIDI I/O device classes name: JUCE audio and MIDI I/O device classes
description: Classes to play and record from audio and MIDI I/O devices description: Classes to play and record from audio and MIDI I/O devices
website: http://www.juce.com/juce website: http://www.juce.com/juce
@@ -140,9 +140,6 @@
//============================================================================== //==============================================================================
namespace juce
{
#include "midi_io/juce_MidiInput.h" #include "midi_io/juce_MidiInput.h"
#include "midi_io/juce_MidiMessageCollector.h" #include "midi_io/juce_MidiMessageCollector.h"
#include "midi_io/juce_MidiOutput.h" #include "midi_io/juce_MidiOutput.h"
@@ -156,5 +153,3 @@ namespace juce
#if JUCE_IOS #if JUCE_IOS
#include "native/juce_ios_Audio.h" #include "native/juce_ios_Audio.h"
#endif #endif
}

+ 4
- 1
source/modules/juce_audio_devices/midi_io/juce_MidiInput.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
class MidiInput; class MidiInput;
@@ -171,3 +172,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
MidiMessageCollector::MidiMessageCollector() MidiMessageCollector::MidiMessageCollector()
{ {
} }
@@ -151,3 +154,5 @@ void MidiMessageCollector::handleIncomingMidiMessage (MidiInput*, const MidiMess
{ {
addMessageToQueue (message); addMessageToQueue (message);
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -99,3 +99,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiMessageCollector) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiMessageCollector)
}; };
} // namespace juce

+ 5
- 0
source/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
struct MidiOutput::PendingMessage struct MidiOutput::PendingMessage
{ {
PendingMessage (const void* const data, const int len, const double timeStamp) PendingMessage (const void* const data, const int len, const double timeStamp)
@@ -169,3 +172,5 @@ void MidiOutput::run()
clearAllPendingMessages(); clearAllPendingMessages();
} }
} // namespace juce

+ 4
- 2
source/modules/juce_audio_devices/midi_io/juce_MidiOutput.h View File

@@ -20,8 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -139,3 +139,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput)
}; };
} // namespace juce

+ 9
- 7
source/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
//============================================================================== //==============================================================================
/** /**
@@ -31,9 +32,8 @@ class MidiDataConcatenator
{ {
public: public:
//============================================================================== //==============================================================================
MidiDataConcatenator (const int initialBufferSize)
: pendingData ((size_t) initialBufferSize),
pendingDataTime (0), pendingBytes (0), runningStatus (0)
MidiDataConcatenator (int initialBufferSize)
: pendingData ((size_t) initialBufferSize)
{ {
} }
@@ -181,9 +181,11 @@ private:
} }
MemoryBlock pendingData; MemoryBlock pendingData;
double pendingDataTime;
int pendingBytes;
uint8 runningStatus;
double pendingDataTime = 0;
int pendingBytes = 0;
uint8 runningStatus = 0;
JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator) JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator)
}; };
} // namespace juce

+ 24
- 1
source/modules/juce_audio_devices/native/juce_android_Audio.cpp View File

@@ -20,7 +20,9 @@
============================================================================== ==============================================================================
*/ */
//==============================================================================
namespace juce
{
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \
STATICMETHOD (getNativeOutputSampleRate, "getNativeOutputSampleRate", "(I)I") \ STATICMETHOD (getNativeOutputSampleRate, "getNativeOutputSampleRate", "(I)I") \
@@ -48,6 +50,13 @@ DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack");
DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord"); DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord");
#undef JNI_CLASS_MEMBERS #undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
STATICFIELD (SDK_INT, "SDK_INT", "I") \
DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION");
#undef JNI_CLASS_MEMBERS
//============================================================================== //==============================================================================
enum enum
{ {
@@ -193,6 +202,9 @@ public:
STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT, STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT,
(jint) (minBufferSizeOut * numDeviceOutputChannels * static_cast<int> (sizeof (int16))), MODE_STREAM)); (jint) (minBufferSizeOut * numDeviceOutputChannels * static_cast<int> (sizeof (int16))), MODE_STREAM));
const bool supportsUnderrunCount = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24);
getUnderrunCount = supportsUnderrunCount ? env->GetMethodID (AudioTrack, "getUnderrunCount", "()I") : 0;
int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState); int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState);
if (outputDeviceState > 0) if (outputDeviceState > 0)
{ {
@@ -279,6 +291,14 @@ public:
String getLastError() override { return lastError; } String getLastError() override { return lastError; }
bool isPlaying() override { return isRunning && callback != 0; } bool isPlaying() override { return isRunning && callback != 0; }
int getXRunCount() const noexcept override
{
if (outputDevice != nullptr && getUnderrunCount != 0)
return getEnv()->CallIntMethod (outputDevice, getUnderrunCount);
return -1;
}
void start (AudioIODeviceCallback* newCallback) override void start (AudioIODeviceCallback* newCallback) override
{ {
if (isRunning && callback != newCallback) if (isRunning && callback != newCallback)
@@ -404,6 +424,7 @@ private:
BigInteger activeOutputChans, activeInputChans; BigInteger activeOutputChans, activeInputChans;
GlobalRef outputDevice, inputDevice; GlobalRef outputDevice, inputDevice;
AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; AudioSampleBuffer inputChannelBuffer, outputChannelBuffer;
jmethodID getUnderrunCount = 0;
void closeDevices() void closeDevices()
{ {
@@ -472,3 +493,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android()
return new AndroidAudioIODeviceType(); return new AndroidAudioIODeviceType();
} }
} // namespace juce

+ 7
- 2
source/modules/juce_audio_devices/native/juce_android_Midi.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (getJuceAndroidMidiInputDevices, "getJuceAndroidMidiInputDevices", "()[Ljava/lang/String;") \ METHOD (getJuceAndroidMidiInputDevices, "getJuceAndroidMidiInputDevices", "()[Ljava/lang/String;") \
METHOD (getJuceAndroidMidiOutputDevices, "getJuceAndroidMidiOutputDevices", "()[Ljava/lang/String;") \ METHOD (getJuceAndroidMidiOutputDevices, "getJuceAndroidMidiOutputDevices", "()[Ljava/lang/String;") \
@@ -89,9 +92,9 @@ public:
jbyte* data = getEnv()->GetByteArrayElements (byteArray, nullptr); jbyte* data = getEnv()->GetByteArrayElements (byteArray, nullptr);
HeapBlock<uint8> buffer (static_cast<size_t> (len)); HeapBlock<uint8> buffer (static_cast<size_t> (len));
std::memcpy (buffer.getData(), data + offset, static_cast<size_t> (len));
std::memcpy (buffer.get(), data + offset, static_cast<size_t> (len));
midiConcatenator.pushMidiData (buffer.getData(),
midiConcatenator.pushMidiData (buffer.get(),
len, static_cast<double> (timestamp) * 1.0e-9, len, static_cast<double> (timestamp) * 1.0e-9,
juceMidiInput, *callback); juceMidiInput, *callback);
@@ -357,3 +360,5 @@ MidiInput::~MidiInput()
{ {
delete reinterpret_cast<AndroidMidiInput*> (internal); delete reinterpret_cast<AndroidMidiInput*> (internal);
} }
} // namespace juce

+ 57
- 21
source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp View File

@@ -20,12 +20,8 @@
============================================================================== ==============================================================================
*/ */
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
STATICFIELD (SDK_INT, "SDK_INT", "I") \
DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION");
#undef JNI_CLASS_MEMBERS
namespace juce
{
//============================================================================== //==============================================================================
#ifndef SL_ANDROID_DATAFORMAT_PCM_EX #ifndef SL_ANDROID_DATAFORMAT_PCM_EX
@@ -289,12 +285,39 @@ public:
nextBlock (0), numBlocksOut (0) nextBlock (0), numBlocksOut (0)
{} {}
~OpenSLQueueRunner()
{
if (config != nullptr && javaProxy != nullptr)
{
javaProxy.clear();
(*config)->ReleaseJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING);
}
}
bool init() bool init()
{ {
runner = crtp().createPlayerOrRecorder(); runner = crtp().createPlayerOrRecorder();
if (runner == nullptr) if (runner == nullptr)
return false; return false;
const bool supportsJavaProxy = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24);
if (supportsJavaProxy)
{
// may return nullptr on some platforms - that's ok
config = SlRef<SLAndroidConfigurationItf_>::cast (runner);
if (config != nullptr)
{
jobject audioRoutingJni;
auto status = (*config)->AcquireJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING,
&audioRoutingJni);
if (status == SL_RESULT_SUCCESS && audioRoutingJni != 0)
javaProxy = GlobalRef (audioRoutingJni);
}
}
queue = SlRef<SLAndroidSimpleBufferQueueItf_>::cast (runner); queue = SlRef<SLAndroidSimpleBufferQueueItf_>::cast (runner);
if (queue == nullptr) if (queue == nullptr)
return false; return false;
@@ -308,7 +331,7 @@ public:
nextBlock.set (0); nextBlock.set (0);
numBlocksOut.set (0); numBlocksOut.set (0);
zeromem (nativeBuffer.getData(), static_cast<size_t> (owner.bufferSize * numChannels * owner.numBuffers) * sizeof (T));
zeromem (nativeBuffer.get(), static_cast<size_t> (owner.bufferSize * numChannels * owner.numBuffers) * sizeof (T));
scratchBuffer.clear(); scratchBuffer.clear();
(*queue)->Clear (queue); (*queue)->Clear (queue);
} }
@@ -321,7 +344,7 @@ public:
bool isBufferAvailable() const { return (numBlocksOut.get() < owner.numBuffers); } bool isBufferAvailable() const { return (numBlocksOut.get() < owner.numBuffers); }
T* getNextBuffer() { nextBlock.set((nextBlock.get() + 1) % owner.numBuffers); return getCurrentBuffer(); } T* getNextBuffer() { nextBlock.set((nextBlock.get() + 1) % owner.numBuffers); return getCurrentBuffer(); }
T* getCurrentBuffer() { return nativeBuffer.getData() + (static_cast<size_t> (nextBlock.get()) * getBufferSizeInSamples()); }
T* getCurrentBuffer() { return nativeBuffer.get() + (static_cast<size_t> (nextBlock.get()) * getBufferSizeInSamples()); }
size_t getBufferSizeInSamples() const { return static_cast<size_t> (owner.bufferSize * numChannels); } size_t getBufferSizeInSamples() const { return static_cast<size_t> (owner.bufferSize * numChannels); }
void finished (SLAndroidSimpleBufferQueueItf) void finished (SLAndroidSimpleBufferQueueItf)
@@ -345,6 +368,8 @@ public:
SlRef<RunnerObjectType> runner; SlRef<RunnerObjectType> runner;
SlRef<SLAndroidSimpleBufferQueueItf_> queue; SlRef<SLAndroidSimpleBufferQueueItf_> queue;
SlRef<SLAndroidConfigurationItf_> config;
GlobalRef javaProxy;
int numChannels; int numChannels;
@@ -377,12 +402,12 @@ public:
SLDataSource source = {&queueLocator, &dataFormat}; SLDataSource source = {&queueLocator, &dataFormat};
SLDataSink sink = {&outputMix, nullptr}; SLDataSink sink = {&outputMix, nullptr};
SLInterfaceID queueInterfaces[] = { &IntfIID<SLAndroidSimpleBufferQueueItf_>::iid };
SLboolean trueFlag = SL_BOOLEAN_TRUE;
SLInterfaceID queueInterfaces[] = { &IntfIID<SLAndroidSimpleBufferQueueItf_>::iid, &IntfIID<SLAndroidConfigurationItf_>::iid };
SLboolean interfaceRequired[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE};
SLObjectItf obj = nullptr; SLObjectItf obj = nullptr;
SLresult status = (*Base::owner.engine)->CreateAudioPlayer (Base::owner.engine, &obj, &source, &sink, 1, queueInterfaces, &trueFlag);
SLresult status = (*Base::owner.engine)->CreateAudioPlayer (Base::owner.engine, &obj, &source, &sink, 2, queueInterfaces, interfaceRequired);
if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS)
{ {
if (obj != nullptr) if (obj != nullptr)
@@ -435,15 +460,12 @@ public:
SlRef<SLRecordItf_> recorder = SlRef<SLRecordItf_>::cast (SlObjectRef (obj)); SlRef<SLRecordItf_> recorder = SlRef<SLRecordItf_>::cast (SlObjectRef (obj));
// may return nullptr on some platforms - that's ok
config = SlRef<SLAndroidConfigurationItf_>::cast (recorder);
return recorder; return recorder;
} }
bool setAudioPreprocessingEnabled (bool shouldEnable) bool setAudioPreprocessingEnabled (bool shouldEnable)
{ {
if (config != nullptr)
if (Base::config != nullptr)
{ {
const bool supportsUnprocessed = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 25); const bool supportsUnprocessed = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 25);
const SLuint32 recordingPresetValue const SLuint32 recordingPresetValue
@@ -451,8 +473,8 @@ public:
: (supportsUnprocessed ? SL_ANDROID_RECORDING_PRESET_UNPROCESSED : (supportsUnprocessed ? SL_ANDROID_RECORDING_PRESET_UNPROCESSED
: SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION)); : SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION));
SLresult status = (*config)->SetConfiguration (config, SL_ANDROID_KEY_RECORDING_PRESET,
&recordingPresetValue, sizeof (recordingPresetValue));
SLresult status = (*Base::config)->SetConfiguration (Base::config, SL_ANDROID_KEY_RECORDING_PRESET,
&recordingPresetValue, sizeof (recordingPresetValue));
return (status == SL_RESULT_SUCCESS); return (status == SL_RESULT_SUCCESS);
} }
@@ -461,8 +483,6 @@ public:
} }
void setState (bool running) { (*Base::runner)->SetRecordState (Base::runner, running ? SL_RECORDSTATE_RECORDING : SL_RECORDSTATE_STOPPED); } void setState (bool running) { (*Base::runner)->SetRecordState (Base::runner, running ? SL_RECORDSTATE_RECORDING : SL_RECORDSTATE_STOPPED); }
SlRef<SLAndroidConfigurationItf_> config;
}; };
//============================================================================== //==============================================================================
@@ -519,6 +539,7 @@ public:
virtual void stop() { running = false; } virtual void stop() { running = false; }
virtual bool setAudioPreprocessingEnabled (bool shouldEnable) = 0; virtual bool setAudioPreprocessingEnabled (bool shouldEnable) = 0;
virtual bool supportsFloatingPoint() const noexcept = 0; virtual bool supportsFloatingPoint() const noexcept = 0;
virtual int getXRunCount() const noexcept = 0;
void setCallback (AudioIODeviceCallback* callbackToUse) void setCallback (AudioIODeviceCallback* callbackToUse)
{ {
@@ -614,6 +635,9 @@ public:
player = nullptr; player = nullptr;
return; return;
} }
const bool supportsUnderrunCount = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24);
getUnderrunCount = supportsUnderrunCount ? getEnv()->GetMethodID (AudioTrack, "getUnderrunCount", "()I") : 0;
} }
} }
} }
@@ -676,6 +700,14 @@ public:
return true; return true;
} }
int getXRunCount() const noexcept override
{
if (player != nullptr && player->javaProxy != nullptr && getUnderrunCount != 0)
return getEnv()->CallIntMethod (player->javaProxy, getUnderrunCount);
return -1;
}
bool supportsFloatingPoint() const noexcept override { return (BufferHelpers<T>::isFloatingPoint != 0); } bool supportsFloatingPoint() const noexcept override { return (BufferHelpers<T>::isFloatingPoint != 0); }
void doSomeWorkOnAudioThread() void doSomeWorkOnAudioThread()
@@ -726,6 +758,7 @@ public:
ScopedPointer<OpenSLQueueRunnerPlayer<T> > player; ScopedPointer<OpenSLQueueRunnerPlayer<T> > player;
ScopedPointer<OpenSLQueueRunnerRecorder<T> > recorder; ScopedPointer<OpenSLQueueRunnerRecorder<T> > recorder;
Atomic<int> guard; Atomic<int> guard;
jmethodID getUnderrunCount = 0;
}; };
//============================================================================== //==============================================================================
@@ -890,6 +923,7 @@ public:
BigInteger getActiveInputChannels() const override { return activeInputChans; } BigInteger getActiveInputChannels() const override { return activeInputChans; }
String getLastError() override { return lastError; } String getLastError() override { return lastError; }
bool isPlaying() override { return callback != nullptr; } bool isPlaying() override { return callback != nullptr; }
int getXRunCount() const noexcept override { return (session != nullptr ? session->getXRunCount() : -1); }
int getDefaultBufferSize() override int getDefaultBufferSize() override
{ {
@@ -1203,11 +1237,11 @@ public:
pthread_t startThread (void* (*entry) (void*), void* userPtr) pthread_t startThread (void* (*entry) (void*), void* userPtr)
{ {
memset (buffer.getData(), 0, static_cast<size_t> (sizeof (int16) * static_cast<size_t> (bufferSize * numBuffers)));
memset (buffer.get(), 0, static_cast<size_t> (sizeof (int16) * static_cast<size_t> (bufferSize * numBuffers)));
for (int i = 0; i < numBuffers; ++i) for (int i = 0; i < numBuffers; ++i)
{ {
int16* dst = buffer.getData() + (bufferSize * i);
int16* dst = buffer.get() + (bufferSize * i);
(*queue)->Enqueue (queue, dst, static_cast<SLuint32> (static_cast<size_t> (bufferSize) * sizeof (int16))); (*queue)->Enqueue (queue, dst, static_cast<SLuint32> (static_cast<size_t> (bufferSize) * sizeof (int16)));
} }
@@ -1283,3 +1317,5 @@ pthread_t juce_createRealtimeAudioThread (void* (*entry) (void*), void* userPtr)
return threadID; return threadID;
} }
} // namespace juce

+ 40
- 4
source/modules/juce_audio_devices/native/juce_ios_Audio.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
class iOSAudioIODevice; class iOSAudioIODevice;
static const char* const iOSAudioDeviceName = "iOS Audio"; static const char* const iOSAudioDeviceName = "iOS Audio";
@@ -183,6 +186,10 @@ bool getNotificationValueForKey (NSNotification* notification, NSString* key, NS
@end @end
//============================================================================== //==============================================================================
#if JUCE_MODULE_AVAILABLE_juce_graphics
#include <juce_graphics/native/juce_mac_CoreGraphicsHelpers.h>
#endif
namespace juce { namespace juce {
#ifndef JUCE_IOS_AUDIO_LOGGING #ifndef JUCE_IOS_AUDIO_LOGGING
@@ -206,10 +213,6 @@ static void logNSError (NSError* e)
#define JUCE_NSERROR_CHECK(X) { NSError* error = nil; X; logNSError (error); } #define JUCE_NSERROR_CHECK(X) { NSError* error = nil; X; logNSError (error); }
#if JUCE_MODULE_AVAILABLE_juce_graphics
#include <juce_graphics/native/juce_mac_CoreGraphicsHelpers.h>
#endif
//============================================================================== //==============================================================================
struct iOSAudioIODevice::Pimpl : public AudioPlayHead, struct iOSAudioIODevice::Pimpl : public AudioPlayHead,
public AsyncUpdater public AsyncUpdater
@@ -310,6 +313,9 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead,
{ {
close(); close();
firstHostTime = true;
lastNumFrames = 0;
xrun = 0;
lastError.clear(); lastError.clear();
preferredBufferSize = bufferSize <= 0 ? defaultBufferSize : bufferSize; preferredBufferSize = bufferSize <= 0 ? defaultBufferSize : bufferSize;
@@ -711,6 +717,8 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead,
{ {
OSStatus err = noErr; OSStatus err = noErr;
recordXruns (time, numFrames);
if (audioInputIsAvailable && numInputChannels > 0) if (audioInputIsAvailable && numInputChannels > 0)
err = AudioUnitRender (audioUnit, flags, time, 1, numFrames, data); err = AudioUnitRender (audioUnit, flags, time, 1, numFrames, data);
@@ -796,6 +804,26 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead,
updateSampleRateAndAudioInput(); updateSampleRateAndAudioInput();
} }
void recordXruns (const AudioTimeStamp* time, UInt32 numFrames)
{
if (time != nullptr && (time->mFlags & kAudioTimeStampSampleTimeValid) != 0)
{
if (! firstHostTime)
{
if ((time->mSampleTime - lastSampleTime) != lastNumFrames)
xrun++;
}
else
firstHostTime = false;
lastSampleTime = time->mSampleTime;
}
else
firstHostTime = true;
lastNumFrames = numFrames;
}
//============================================================================== //==============================================================================
static OSStatus processStatic (void* client, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time, static OSStatus processStatic (void* client, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time,
UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data) UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data)
@@ -1060,6 +1088,11 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead,
float* outputChannels[3]; float* outputChannels[3];
bool monoInputChannelNumber, monoOutputChannelNumber; bool monoInputChannelNumber, monoOutputChannelNumber;
bool firstHostTime;
Float64 lastSampleTime;
unsigned int lastNumFrames;
int xrun;
JUCE_DECLARE_NON_COPYABLE (Pimpl) JUCE_DECLARE_NON_COPYABLE (Pimpl)
}; };
@@ -1105,6 +1138,7 @@ BigInteger iOSAudioIODevice::getActiveInputChannels() const { return pim
int iOSAudioIODevice::getOutputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].outputLatency); } int iOSAudioIODevice::getOutputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].outputLatency); }
int iOSAudioIODevice::getInputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].inputLatency); } int iOSAudioIODevice::getInputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].inputLatency); }
int iOSAudioIODevice::getXRunCount() const noexcept { return pimpl->xrun; }
void iOSAudioIODevice::setMidiMessageCollector (MidiMessageCollector* collector) { pimpl->messageCollector = collector; } void iOSAudioIODevice::setMidiMessageCollector (MidiMessageCollector* collector) { pimpl->messageCollector = collector; }
AudioPlayHead* iOSAudioIODevice::getAudioPlayHead() const { return pimpl; } AudioPlayHead* iOSAudioIODevice::getAudioPlayHead() const { return pimpl; }
@@ -1168,3 +1202,5 @@ void AudioSessionHolder::handleRouteChange (const char* reason)
} }
#undef JUCE_NSERROR_CHECK #undef JUCE_NSERROR_CHECK
} // namespace juce

+ 6
- 1
source/modules/juce_audio_devices/native/juce_ios_Audio.h View File

@@ -20,7 +20,8 @@
============================================================================== ==============================================================================
*/ */
#pragma once
namespace juce
{
struct iOSAudioIODeviceType; struct iOSAudioIODeviceType;
@@ -61,6 +62,8 @@ public:
int getOutputLatencyInSamples() override; int getOutputLatencyInSamples() override;
int getInputLatencyInSamples() override; int getInputLatencyInSamples() override;
int getXRunCount() const noexcept override;
//============================================================================== //==============================================================================
void setMidiMessageCollector (MidiMessageCollector*); void setMidiMessageCollector (MidiMessageCollector*);
AudioPlayHead* getAudioPlayHead() const; AudioPlayHead* getAudioPlayHead() const;
@@ -86,3 +89,5 @@ private:
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice)
}; };
} // namespace juce

+ 77
- 24
source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
namespace namespace
{ {
@@ -75,7 +78,7 @@ static void getDeviceNumChannels (snd_pcm_t* handle, unsigned int* minChans, uns
JUCE_ALSA_LOG ("getDeviceNumChannels: " << (int) *minChans << " " << (int) *maxChans); JUCE_ALSA_LOG ("getDeviceNumChannels: " << (int) *minChans << " " << (int) *maxChans);
// some virtual devices (dmix for example) report 10000 channels , we have to clamp these values // some virtual devices (dmix for example) report 10000 channels , we have to clamp these values
*maxChans = jmin (*maxChans, 32u);
*maxChans = jmin (*maxChans, 256u);
*minChans = jmin (*minChans, *maxChans); *minChans = jmin (*minChans, *maxChans);
} }
else else
@@ -155,7 +158,7 @@ public:
isInput (forInput), isInput (forInput),
isInterleaved (true) isInterleaved (true)
{ {
JUCE_ALSA_LOG ("snd_pcm_open (" << deviceID.toUTF8().getAddress() << ", forInput=" << forInput << ")");
JUCE_ALSA_LOG ("snd_pcm_open (" << deviceID.toUTF8().getAddress() << ", forInput=" << (int) forInput << ")");
int err = snd_pcm_open (&handle, deviceID.toUTF8(), int err = snd_pcm_open (&handle, deviceID.toUTF8(),
forInput ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, forInput ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
@@ -241,7 +244,8 @@ public:
(type & isFloatBit) != 0, (type & isFloatBit) != 0,
(type & isLittleEndianBit) != 0, (type & isLittleEndianBit) != 0,
(type & onlyUseLower24Bits) != 0, (type & onlyUseLower24Bits) != 0,
numChannels);
numChannels,
isInterleaved);
break; break;
} }
} }
@@ -329,8 +333,14 @@ public:
numDone = snd_pcm_writen (handle, (void**) data, (snd_pcm_uframes_t) numSamples); numDone = snd_pcm_writen (handle, (void**) data, (snd_pcm_uframes_t) numSamples);
} }
if (numDone < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) numDone, 1 /* silent */)))
return false;
if (numDone < 0)
{
if (numDone == -(EPIPE))
underrunCount++;
if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) numDone, 1 /* silent */)))
return false;
}
if (numDone < numSamples) if (numDone < numSamples)
JUCE_ALSA_LOG ("Did not write all samples: numDone: " << numDone << ", numSamples: " << numSamples); JUCE_ALSA_LOG ("Did not write all samples: numDone: " << numDone << ", numSamples: " << numSamples);
@@ -350,8 +360,15 @@ public:
snd_pcm_sframes_t num = snd_pcm_readi (handle, scratch.getData(), (snd_pcm_uframes_t) numSamples); snd_pcm_sframes_t num = snd_pcm_readi (handle, scratch.getData(), (snd_pcm_uframes_t) numSamples);
if (num < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */)))
return false;
if (num < 0)
{
if (num == -(EPIPE))
overrunCount++;
if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */)))
return false;
}
if (num < numSamples) if (num < numSamples)
JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples); JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples);
@@ -363,8 +380,14 @@ public:
{ {
snd_pcm_sframes_t num = snd_pcm_readn (handle, (void**) data, (snd_pcm_uframes_t) numSamples); snd_pcm_sframes_t num = snd_pcm_readn (handle, (void**) data, (snd_pcm_uframes_t) numSamples);
if (num < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */)))
return false;
if (num < 0)
{
if (num == -(EPIPE))
overrunCount++;
if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */)))
return false;
}
if (num < numSamples) if (num < numSamples)
JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples); JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples);
@@ -380,6 +403,7 @@ public:
snd_pcm_t* handle; snd_pcm_t* handle;
String error; String error;
int bitDepth, numChannelsRunning, latency; int bitDepth, numChannelsRunning, latency;
int underrunCount = 0, overrunCount = 0;
private: private:
//============================================================================== //==============================================================================
@@ -393,44 +417,55 @@ private:
template <class SampleType> template <class SampleType>
struct ConverterHelper struct ConverterHelper
{ {
static AudioData::Converter* createConverter (const bool forInput, const bool isLittleEndian, const int numInterleavedChannels)
static AudioData::Converter* createConverter (const bool forInput, const bool isLittleEndian, const int numInterleavedChannels, bool interleaved)
{
if (interleaved)
return create<AudioData::Interleaved> (forInput, isLittleEndian, numInterleavedChannels);
return create<AudioData::NonInterleaved> (forInput, isLittleEndian, numInterleavedChannels);
}
private:
template <class InterleavedType>
static AudioData::Converter* create (const bool forInput, const bool isLittleEndian, const int numInterleavedChannels)
{ {
if (forInput) if (forInput)
{ {
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestType; typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestType;
if (isLittleEndian) if (isLittleEndian)
return new AudioData::ConverterInstance <AudioData::Pointer <SampleType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::Const>, DestType> (numInterleavedChannels, 1);
return new AudioData::ConverterInstance <AudioData::Pointer <SampleType, AudioData::LittleEndian, InterleavedType, AudioData::Const>, DestType> (numInterleavedChannels, 1);
return new AudioData::ConverterInstance <AudioData::Pointer <SampleType, AudioData::BigEndian, AudioData::Interleaved, AudioData::Const>, DestType> (numInterleavedChannels, 1);
return new AudioData::ConverterInstance <AudioData::Pointer <SampleType, AudioData::BigEndian, InterleavedType, AudioData::Const>, DestType> (numInterleavedChannels, 1);
} }
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceType; typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceType;
if (isLittleEndian) if (isLittleEndian)
return new AudioData::ConverterInstance <SourceType, AudioData::Pointer <SampleType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::NonConst> > (1, numInterleavedChannels);
return new AudioData::ConverterInstance <SourceType, AudioData::Pointer <SampleType, AudioData::LittleEndian, InterleavedType, AudioData::NonConst> > (1, numInterleavedChannels);
return new AudioData::ConverterInstance <SourceType, AudioData::Pointer <SampleType, AudioData::BigEndian, AudioData::Interleaved, AudioData::NonConst> > (1, numInterleavedChannels);
return new AudioData::ConverterInstance <SourceType, AudioData::Pointer <SampleType, AudioData::BigEndian, InterleavedType, AudioData::NonConst> > (1, numInterleavedChannels);
} }
}; };
static AudioData::Converter* createConverter (bool forInput, int bitDepth, static AudioData::Converter* createConverter (bool forInput, int bitDepth,
bool isFloat, bool isLittleEndian, bool useOnlyLower24Bits, bool isFloat, bool isLittleEndian, bool useOnlyLower24Bits,
int numInterleavedChannels)
int numInterleavedChannels,
bool interleaved)
{ {
JUCE_ALSA_LOG ("format: bitDepth=" << bitDepth << ", isFloat=" << isFloat
<< ", isLittleEndian=" << isLittleEndian << ", numChannels=" << numInterleavedChannels);
JUCE_ALSA_LOG ("format: bitDepth=" << bitDepth << ", isFloat=" << (int) isFloat
<< ", isLittleEndian=" << (int) isLittleEndian << ", numChannels=" << numInterleavedChannels);
if (isFloat) return ConverterHelper <AudioData::Float32>::createConverter (forInput, isLittleEndian, numInterleavedChannels);
if (bitDepth == 16) return ConverterHelper <AudioData::Int16> ::createConverter (forInput, isLittleEndian, numInterleavedChannels);
if (bitDepth == 24) return ConverterHelper <AudioData::Int24> ::createConverter (forInput, isLittleEndian, numInterleavedChannels);
if (isFloat) return ConverterHelper <AudioData::Float32>::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved);
if (bitDepth == 16) return ConverterHelper <AudioData::Int16> ::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved);
if (bitDepth == 24) return ConverterHelper <AudioData::Int24> ::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved);
jassert (bitDepth == 32); jassert (bitDepth == 32);
if (useOnlyLower24Bits) if (useOnlyLower24Bits)
return ConverterHelper <AudioData::Int24in32>::createConverter (forInput, isLittleEndian, numInterleavedChannels);
return ConverterHelper <AudioData::Int24in32>::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved);
return ConverterHelper <AudioData::Int32>::createConverter (forInput, isLittleEndian, numInterleavedChannels);
return ConverterHelper <AudioData::Int32>::createConverter (forInput, isLittleEndian, numInterleavedChannels, interleaved);
} }
//============================================================================== //==============================================================================
@@ -734,6 +769,19 @@ public:
return 16; return 16;
} }
int getXRunCount() const noexcept
{
int result = 0;
if (outputDevice != nullptr)
result += outputDevice->underrunCount;
if (inputDevice != nullptr)
result += inputDevice->overrunCount;
return result;
}
//============================================================================== //==============================================================================
String error; String error;
double sampleRate; double sampleRate;
@@ -893,6 +941,8 @@ public:
int getOutputLatencyInSamples() override { return internal.outputLatency; } int getOutputLatencyInSamples() override { return internal.outputLatency; }
int getInputLatencyInSamples() override { return internal.inputLatency; } int getInputLatencyInSamples() override { return internal.inputLatency; }
int getXRunCount() const noexcept override { return internal.getXRunCount(); }
void start (AudioIODeviceCallback* callback) override void start (AudioIODeviceCallback* callback) override
{ {
if (! isOpen_) if (! isOpen_)
@@ -1037,7 +1087,7 @@ private:
if ((isInput || isOutput) && rates.size() > 0) if ((isInput || isOutput) && rates.size() > 0)
{ {
JUCE_ALSA_LOG ("testDevice: '" << id.toUTF8().getAddress() << "' -> isInput: " JUCE_ALSA_LOG ("testDevice: '" << id.toUTF8().getAddress() << "' -> isInput: "
<< isInput << ", isOutput: " << isOutput);
<< (int) isInput << ", isOutput: " << (int) isOutput);
if (isInput) if (isInput)
{ {
@@ -1128,7 +1178,8 @@ private:
} }
JUCE_ALSA_LOG ("Soundcard ID: " << id << ", name: '" << name JUCE_ALSA_LOG ("Soundcard ID: " << id << ", name: '" << name
<< ", isInput:" << isInput << ", isOutput:" << isOutput << "\n");
<< ", isInput:" << (int) isInput
<< ", isOutput:" << (int) isOutput << "\n");
if (isInput) if (isInput)
{ {
@@ -1259,3 +1310,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA()
{ {
return createAudioIODeviceType_ALSA_PCMDevices(); return createAudioIODeviceType_ALSA_PCMDevices();
} }
} // namespace juce

+ 21
- 1
source/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp View File

@@ -20,7 +20,9 @@
============================================================================== ==============================================================================
*/ */
//==============================================================================
namespace juce
{
static void* juce_libjackHandle = nullptr; static void* juce_libjackHandle = nullptr;
static void* juce_loadJackFunction (const char* const name) static void* juce_loadJackFunction (const char* const name)
@@ -67,6 +69,7 @@ JUCE_DECL_JACK_FUNCTION (void*, jack_set_port_connect_callback, (jack_client_t*
JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_by_id, (jack_client_t* client, jack_port_id_t port_id), (client, port_id)); JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_by_id, (jack_client_t* client, jack_port_id_t port_id), (client, port_id));
JUCE_DECL_JACK_FUNCTION (int, jack_port_connected, (const jack_port_t* port), (port)); JUCE_DECL_JACK_FUNCTION (int, jack_port_connected, (const jack_port_t* port), (port));
JUCE_DECL_JACK_FUNCTION (int, jack_port_connected_to, (const jack_port_t* port, const char* port_name), (port, port_name)); JUCE_DECL_JACK_FUNCTION (int, jack_port_connected_to, (const jack_port_t* port, const char* port_name), (port, port_name));
JUCE_DECL_JACK_FUNCTION (int, jack_set_xrun_callback, (jack_client_t* client, JackXRunCallback xrun_callback, void* arg), (client, xrun_callback, arg));
#if JUCE_DEBUG #if JUCE_DEBUG
#define JACK_LOGGING_ENABLED 1 #define JACK_LOGGING_ENABLED 1
@@ -256,9 +259,11 @@ public:
lastError.clear(); lastError.clear();
close(); close();
xruns = 0;
juce::jack_set_process_callback (client, processCallback, this); juce::jack_set_process_callback (client, processCallback, this);
juce::jack_set_port_connect_callback (client, portConnectCallback, this); juce::jack_set_port_connect_callback (client, portConnectCallback, this);
juce::jack_on_shutdown (client, shutdownCallback, this); juce::jack_on_shutdown (client, shutdownCallback, this);
juce::jack_set_xrun_callback (client, xrunCallback, this);
juce::jack_activate (client); juce::jack_activate (client);
deviceIsOpen = true; deviceIsOpen = true;
@@ -300,6 +305,8 @@ public:
if (client != nullptr) if (client != nullptr)
{ {
juce::jack_deactivate (client); juce::jack_deactivate (client);
juce::jack_set_xrun_callback (client, xrunCallback, nullptr);
juce::jack_set_process_callback (client, processCallback, nullptr); juce::jack_set_process_callback (client, processCallback, nullptr);
juce::jack_set_port_connect_callback (client, portConnectCallback, nullptr); juce::jack_set_port_connect_callback (client, portConnectCallback, nullptr);
juce::jack_on_shutdown (client, shutdownCallback, nullptr); juce::jack_on_shutdown (client, shutdownCallback, nullptr);
@@ -336,6 +343,7 @@ public:
bool isPlaying() override { return callback != nullptr; } bool isPlaying() override { return callback != nullptr; }
int getCurrentBitDepth() override { return 32; } int getCurrentBitDepth() override { return 32; }
String getLastError() override { return lastError; } String getLastError() override { return lastError; }
int getXRunCount() const noexcept override { return xruns; }
BigInteger getActiveOutputChannels() const override { return activeOutputChannels; } BigInteger getActiveOutputChannels() const override { return activeOutputChannels; }
BigInteger getActiveInputChannels() const override { return activeInputChannels; } BigInteger getActiveInputChannels() const override { return activeInputChannels; }
@@ -406,6 +414,14 @@ private:
return 0; return 0;
} }
static int xrunCallback (void* callbackArgument)
{
if (callbackArgument != nullptr)
((JackAudioIODevice*) callbackArgument)->xruns++;
return 0;
}
void updateActivePorts() void updateActivePorts()
{ {
BigInteger newOutputChannels, newInputChannels; BigInteger newOutputChannels, newInputChannels;
@@ -475,6 +491,8 @@ private:
int totalNumberOfOutputChannels; int totalNumberOfOutputChannels;
Array<void*> inputPorts, outputPorts; Array<void*> inputPorts, outputPorts;
BigInteger activeInputChannels, activeOutputChannels; BigInteger activeInputChannels, activeOutputChannels;
int xruns;
}; };
@@ -602,3 +620,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK()
{ {
return new JackAudioIODeviceType(); return new JackAudioIODeviceType();
} }
} // namespace juce

+ 6
- 1
source/modules/juce_audio_devices/native/juce_linux_Midi.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
#if JUCE_ALSA #if JUCE_ALSA
// You can define these strings in your app if you want to override the default names: // You can define these strings in your app if you want to override the default names:
@@ -137,7 +140,7 @@ public:
numBytes -= numSent; numBytes -= numSent;
data += numSent; data += numSent;
snd_seq_ev_set_source (&event, portId);
snd_seq_ev_set_source (&event, (unsigned char) portId);
snd_seq_ev_set_subs (&event); snd_seq_ev_set_subs (&event);
snd_seq_ev_set_direct (&event); snd_seq_ev_set_direct (&event);
@@ -610,3 +613,5 @@ MidiInput* MidiInput::openDevice (int, MidiInputCallback*) { re
MidiInput* MidiInput::createNewDevice (const String&, MidiInputCallback*) { return nullptr; } MidiInput* MidiInput::createNewDevice (const String&, MidiInputCallback*) { return nullptr; }
#endif #endif
} // namespace juce

+ 15
- 2
source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
#if JUCE_COREAUDIO_LOGGING_ENABLED #if JUCE_COREAUDIO_LOGGING_ENABLED
#define JUCE_COREAUDIOLOG(a) { String camsg ("CoreAudio: "); camsg << a; Logger::writeToLog (camsg); } #define JUCE_COREAUDIOLOG(a) { String camsg ("CoreAudio: "); camsg << a; Logger::writeToLog (camsg); }
#else #else
@@ -228,7 +231,7 @@ public:
for (int i = 0; i < numStreams; ++i) for (int i = 0; i < numStreams; ++i)
{ {
const ::AudioBuffer& b = bufList->mBuffers[i];
auto& b = bufList->mBuffers[i];
for (unsigned int j = 0; j < b.mNumberChannels; ++j) for (unsigned int j = 0; j < b.mNumberChannels; ++j)
{ {
@@ -578,6 +581,8 @@ public:
stop (false); stop (false);
updateDetailsFromDevice();
activeInputChans = inputChannels; activeInputChans = inputChannels;
activeInputChans.setRange (inChanNames.size(), activeInputChans.setRange (inChanNames.size(),
activeInputChans.getHighestBit() + 1 - inChanNames.size(), activeInputChans.getHighestBit() + 1 - inChanNames.size(),
@@ -733,7 +738,7 @@ public:
} }
} }
callback->audioDeviceIOCallback (const_cast<const float**> (tempInputBuffers.getData()),
callback->audioDeviceIOCallback (const_cast<const float**> (tempInputBuffers.get()),
numInputChans, numInputChans,
tempOutputBuffers, tempOutputBuffers,
numOutputChans, numOutputChans,
@@ -791,6 +796,7 @@ public:
int inputLatency = 0; int inputLatency = 0;
int outputLatency = 0; int outputLatency = 0;
int bitDepth = 32; int bitDepth = 32;
int xruns = 0;
BigInteger activeInputChans, activeOutputChans; BigInteger activeInputChans, activeOutputChans;
StringArray inChanNames, outChanNames; StringArray inChanNames, outChanNames;
Array<double> sampleRates; Array<double> sampleRates;
@@ -832,6 +838,9 @@ private:
switch (pa->mSelector) switch (pa->mSelector)
{ {
case kAudioDeviceProcessorOverload:
intern->xruns++;
break;
case kAudioDevicePropertyBufferSize: case kAudioDevicePropertyBufferSize:
case kAudioDevicePropertyBufferFrameSize: case kAudioDevicePropertyBufferFrameSize:
case kAudioDevicePropertyNominalSampleRate: case kAudioDevicePropertyNominalSampleRate:
@@ -957,6 +966,7 @@ public:
double getCurrentSampleRate() override { return internal->getSampleRate(); } double getCurrentSampleRate() override { return internal->getSampleRate(); }
int getCurrentBitDepth() override { return internal->bitDepth; } int getCurrentBitDepth() override { return internal->bitDepth; }
int getCurrentBufferSizeSamples() override { return internal->getBufferSize(); } int getCurrentBufferSizeSamples() override { return internal->getBufferSize(); }
int getXRunCount() const noexcept override { return internal->xruns; }
int getDefaultBufferSize() override int getDefaultBufferSize() override
{ {
@@ -977,6 +987,7 @@ public:
{ {
isOpen_ = true; isOpen_ = true;
internal->xruns = 0;
if (bufferSizeSamples <= 0) if (bufferSizeSamples <= 0)
bufferSizeSamples = getDefaultBufferSize(); bufferSizeSamples = getDefaultBufferSize();
@@ -2058,3 +2069,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio()
} }
#undef JUCE_COREAUDIOLOG #undef JUCE_COREAUDIOLOG
} // namespace juce

+ 5
- 0
source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
#ifndef JUCE_LOG_COREMIDI_ERRORS #ifndef JUCE_LOG_COREMIDI_ERRORS
#define JUCE_LOG_COREMIDI_ERRORS 1 #define JUCE_LOG_COREMIDI_ERRORS 1
#endif #endif
@@ -555,3 +558,5 @@ void MidiInput::stop()
} }
#undef CHECK_ERROR #undef CHECK_ERROR
} // namespace juce

+ 15
- 2
source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
#undef WINDOWS #undef WINDOWS
/* The ASIO SDK *should* declare its callback functions as being __cdecl, but different versions seem /* The ASIO SDK *should* declare its callback functions as being __cdecl, but different versions seem
@@ -406,6 +409,8 @@ public:
Array<int> getAvailableBufferSizes() override { return bufferSizes; } Array<int> getAvailableBufferSizes() override { return bufferSizes; }
int getDefaultBufferSize() override { return preferredBufferSize; } int getDefaultBufferSize() override { return preferredBufferSize; }
int getXRunCount() const noexcept override { return xruns; }
String open (const BigInteger& inputChannels, String open (const BigInteger& inputChannels,
const BigInteger& outputChannels, const BigInteger& outputChannels,
double sr, int bufferSizeSamples) override double sr, int bufferSizeSamples) override
@@ -461,6 +466,9 @@ public:
err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans); err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans);
jassert (err == ASE_OK); jassert (err == ASE_OK);
if (asioObject->future (kAsioCanReportOverload, nullptr) != ASE_OK)
xruns = -1;
inBuffers.calloc (totalNumInputChans + 8); inBuffers.calloc (totalNumInputChans + 8);
outBuffers.calloc (totalNumOutputChans + 8); outBuffers.calloc (totalNumOutputChans + 8);
@@ -786,6 +794,7 @@ private:
bool volatile littleEndian, postOutput, needToReset; bool volatile littleEndian, postOutput, needToReset;
bool volatile insideControlPanelModalLoop; bool volatile insideControlPanelModalLoop;
bool volatile shouldUsePreferredSize; bool volatile shouldUsePreferredSize;
int xruns = 0;
//============================================================================== //==============================================================================
static String convertASIOString (char* const text, int length) static String convertASIOString (char* const text, int length)
@@ -1177,6 +1186,7 @@ private:
totalNumOutputChans = 0; totalNumOutputChans = 0;
numActiveInputChans = 0; numActiveInputChans = 0;
numActiveOutputChans = 0; numActiveOutputChans = 0;
xruns = 0;
currentCallback = nullptr; currentCallback = nullptr;
error.clear(); error.clear();
@@ -1346,7 +1356,7 @@ private:
{ {
case kAsioSelectorSupported: case kAsioSelectorSupported:
if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest
|| value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor)
|| value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor || value == kAsioOverload)
return 1; return 1;
break; break;
@@ -1357,7 +1367,8 @@ private:
case kAsioEngineVersion: return 2; case kAsioEngineVersion: return 2;
case kAsioSupportsTimeInfo: case kAsioSupportsTimeInfo:
case kAsioSupportsTimeCode: return 0;
case kAsioSupportsTimeCode: return 0;
case kAsioOverload: xruns++; return 1;
} }
return 0; return 0;
@@ -1643,3 +1654,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO()
{ {
return new ASIOAudioIODeviceType(); return new ASIOAudioIODeviceType();
} }
} // namespace juce

+ 31
- 3
source/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp View File

@@ -20,8 +20,6 @@
============================================================================== ==============================================================================
*/ */
} // (juce namespace)
extern "C" extern "C"
{ {
// Declare just the minimum number of interfaces for the DSound objects that we need.. // Declare just the minimum number of interfaces for the DSound objects that we need..
@@ -268,6 +266,10 @@ public:
pDirectSound = nullptr; pDirectSound = nullptr;
pOutputBuffer = nullptr; pOutputBuffer = nullptr;
writeOffset = 0; writeOffset = 0;
xruns = 0;
firstPlayTime = true;
lastPlayTime = 0;
String error; String error;
HRESULT hr = E_NOINTERFACE; HRESULT hr = E_NOINTERFACE;
@@ -278,6 +280,7 @@ public:
if (SUCCEEDED (hr)) if (SUCCEEDED (hr))
{ {
bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15; bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15;
ticksPerBuffer = bytesPerBuffer * Time::getHighResolutionTicksPerSecond() / (sampleRate * (bitDepth >> 2));
totalBytesPerBuffer = (blocksPerOverallBuffer * bytesPerBuffer) & ~15; totalBytesPerBuffer = (blocksPerOverallBuffer * bytesPerBuffer) & ~15;
const int numChannels = 2; const int numChannels = 2;
@@ -399,6 +402,18 @@ public:
return true; return true;
} }
auto currentPlayTime = Time::getHighResolutionTicks ();
if (! firstPlayTime)
{
auto expectedBuffers = (currentPlayTime - lastPlayTime) / ticksPerBuffer;
playCursor += static_cast<DWORD> (expectedBuffers * bytesPerBuffer);
}
else
firstPlayTime = false;
lastPlayTime = currentPlayTime;
int playWriteGap = (int) (writeCursor - playCursor); int playWriteGap = (int) (writeCursor - playCursor);
if (playWriteGap < 0) if (playWriteGap < 0)
playWriteGap += totalBytesPerBuffer; playWriteGap += totalBytesPerBuffer;
@@ -411,6 +426,9 @@ public:
{ {
writeOffset = writeCursor; writeOffset = writeCursor;
bytesEmpty = totalBytesPerBuffer - playWriteGap; bytesEmpty = totalBytesPerBuffer - playWriteGap;
// buffer underflow
xruns++;
} }
if (bytesEmpty >= bytesPerBuffer) if (bytesEmpty >= bytesPerBuffer)
@@ -482,7 +500,7 @@ public:
} }
} }
int bitDepth;
int bitDepth, xruns;
bool doneFlag; bool doneFlag;
private: private:
@@ -498,6 +516,9 @@ private:
int totalBytesPerBuffer, bytesPerBuffer; int totalBytesPerBuffer, bytesPerBuffer;
unsigned int lastPlayCursor; unsigned int lastPlayCursor;
bool firstPlayTime;
int64 lastPlayTime, ticksPerBuffer;
static inline int convertInputValues (const float l, const float r) noexcept static inline int convertInputValues (const float l, const float r) noexcept
{ {
return jlimit (-32768, 32767, roundToInt (32767.0f * r)) << 16 return jlimit (-32768, 32767, roundToInt (32767.0f * r)) << 16
@@ -856,6 +877,11 @@ public:
bool isPlaying() override { return isStarted && isOpen_ && isThreadRunning(); } bool isPlaying() override { return isStarted && isOpen_ && isThreadRunning(); }
String getLastError() override { return lastError; } String getLastError() override { return lastError; }
int getXRunCount () const noexcept override
{
return (outChans[0] != nullptr ? outChans[0]->xruns : -1);
}
//============================================================================== //==============================================================================
StringArray inChannels, outChannels; StringArray inChannels, outChannels;
int outputDeviceIndex, inputDeviceIndex; int outputDeviceIndex, inputDeviceIndex;
@@ -1271,3 +1297,5 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound()
{ {
return new DSoundAudioIODeviceType(); return new DSoundAudioIODeviceType();
} }
} // namespace juce

+ 16
- 18
source/modules/juce_audio_devices/native/juce_win32_Midi.cpp View File

@@ -20,6 +20,9 @@
============================================================================== ==============================================================================
*/ */
namespace juce
{
struct MidiServiceType struct MidiServiceType
{ {
struct InputWrapper struct InputWrapper
@@ -27,7 +30,6 @@ struct MidiServiceType
virtual ~InputWrapper() {} virtual ~InputWrapper() {}
virtual String getDeviceName() = 0; virtual String getDeviceName() = 0;
virtual void start() = 0; virtual void start() = 0;
virtual void stop() = 0; virtual void stop() = 0;
}; };
@@ -37,7 +39,6 @@ struct MidiServiceType
virtual ~OutputWrapper() {} virtual ~OutputWrapper() {}
virtual String getDeviceName() = 0; virtual String getDeviceName() = 0;
virtual void sendMessageNow (const MidiMessage&) = 0; virtual void sendMessageNow (const MidiMessage&) = 0;
}; };
@@ -47,10 +48,8 @@ struct MidiServiceType
virtual StringArray getDevices (bool) = 0; virtual StringArray getDevices (bool) = 0;
virtual int getDefaultDeviceIndex (bool) = 0; virtual int getDefaultDeviceIndex (bool) = 0;
virtual InputWrapper* createInputWrapper (MidiInput* const,
const int,
MidiInputCallback* const callback) = 0;
virtual OutputWrapper* createOutputWrapper (const int) = 0;
virtual InputWrapper* createInputWrapper (MidiInput*, int, MidiInputCallback*) = 0;
virtual OutputWrapper* createOutputWrapper (int) = 0;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiServiceType) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiServiceType)
}; };
@@ -510,14 +509,12 @@ public:
: WindowsOutputWrapper::getDefaultDeviceIndex(); : WindowsOutputWrapper::getDefaultDeviceIndex();
} }
InputWrapper* createInputWrapper (MidiInput* const input,
const int index,
MidiInputCallback* const callback) override
InputWrapper* createInputWrapper (MidiInput* input, int index, MidiInputCallback* callback) override
{ {
return new WindowsInputWrapper (*this, input, index, callback); return new WindowsInputWrapper (*this, input, index, callback);
} }
OutputWrapper* createOutputWrapper (const int index) override
OutputWrapper* createOutputWrapper (int index) override
{ {
return new WindowsOutputWrapper (*this, index); return new WindowsOutputWrapper (*this, index);
} }
@@ -1001,7 +998,7 @@ private:
if (bufferFactory == nullptr) if (bufferFactory == nullptr)
throw std::runtime_error ("Failed to create output buffer factory"); throw std::runtime_error ("Failed to create output buffer factory");
HRESULT hr = bufferFactory->Create (static_cast<UINT32> (256), buffer.resetAndGetPointerAddress());
HRESULT hr = bufferFactory->Create (static_cast<UINT32> (65536), buffer.resetAndGetPointerAddress());
if (FAILED (hr)) if (FAILED (hr))
throw std::runtime_error ("Failed to create output buffer"); throw std::runtime_error ("Failed to create output buffer");
@@ -1081,14 +1078,12 @@ public:
: outputDeviceWatcher->getDefaultDeviceIndex(); : outputDeviceWatcher->getDefaultDeviceIndex();
} }
InputWrapper* createInputWrapper (MidiInput* const input,
const int index,
MidiInputCallback* const callback) override
InputWrapper* createInputWrapper (MidiInput* input, int index, MidiInputCallback* callback) override
{ {
return new WinRTInputWrapper (*this, input, index, *callback); return new WinRTInputWrapper (*this, input, index, *callback);
} }
OutputWrapper* createOutputWrapper (const int index) override
OutputWrapper* createOutputWrapper (int index) override
{ {
return new WinRTOutputWrapper (*this, index); return new WinRTOutputWrapper (*this, index);
} }
@@ -1169,8 +1164,9 @@ MidiInput* MidiInput::openDevice (const int index, MidiInputCallback* const call
if (callback == nullptr) if (callback == nullptr)
return nullptr; return nullptr;
ScopedPointer<MidiInput> in (new MidiInput (""));
ScopedPointer<MidiInput> in (new MidiInput ({}));
ScopedPointer<MidiServiceType::InputWrapper> wrapper; ScopedPointer<MidiServiceType::InputWrapper> wrapper;
try try
{ {
wrapper = MidiService::getInstance()->getService()->createInputWrapper (in, index, callback); wrapper = MidiService::getInstance()->getService()->createInputWrapper (in, index, callback);
@@ -1207,6 +1203,7 @@ int MidiOutput::getDefaultDeviceIndex()
MidiOutput* MidiOutput::openDevice (const int index) MidiOutput* MidiOutput::openDevice (const int index)
{ {
ScopedPointer<MidiServiceType::OutputWrapper> wrapper; ScopedPointer<MidiServiceType::OutputWrapper> wrapper;
try try
{ {
wrapper = MidiService::getInstance()->getService()->createOutputWrapper (index); wrapper = MidiService::getInstance()->getService()->createOutputWrapper (index);
@@ -1229,6 +1226,7 @@ MidiOutput::~MidiOutput()
void MidiOutput::sendMessageNow (const MidiMessage& message) void MidiOutput::sendMessageNow (const MidiMessage& message)
{ {
auto* const wrapper = static_cast<MidiServiceType::OutputWrapper*> (internal);
wrapper->sendMessageNow (message);
static_cast<MidiServiceType::OutputWrapper*> (internal)->sendMessageNow (message);
} }
} // namespace juce

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save