upgrade to JUCE 5.4.3. Remove (probably) unused JUCE modules. Remove VST2 target (it's been end-of-life'd by Steinberg and by JUCE)
This commit is contained in:
		@ -651,7 +651,7 @@ public:
 | 
			
		||||
        writeHeader();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~AiffAudioFormatWriter()
 | 
			
		||||
    ~AiffAudioFormatWriter() override
 | 
			
		||||
    {
 | 
			
		||||
        if ((bytesWritten & 1) != 0)
 | 
			
		||||
            output->writeByte (0);
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ public:
 | 
			
		||||
    AiffAudioFormat();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~AiffAudioFormat();
 | 
			
		||||
    ~AiffAudioFormat() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Metadata property name used when reading a aiff file with a basc chunk. */
 | 
			
		||||
 | 
			
		||||
@ -42,9 +42,9 @@ namespace
 | 
			
		||||
        CFArrayRef extensions = nullptr;
 | 
			
		||||
        UInt32 sizeOfArray = sizeof (extensions);
 | 
			
		||||
 | 
			
		||||
        if (AudioFileGetGlobalInfo (kAudioFileGlobalInfo_AllExtensions, 0, 0, &sizeOfArray, &extensions) == noErr)
 | 
			
		||||
        if (AudioFileGetGlobalInfo (kAudioFileGlobalInfo_AllExtensions, 0, nullptr, &sizeOfArray, &extensions) == noErr)
 | 
			
		||||
        {
 | 
			
		||||
            const CFIndex numValues = CFArrayGetCount (extensions);
 | 
			
		||||
            auto numValues = CFArrayGetCount (extensions);
 | 
			
		||||
 | 
			
		||||
            for (CFIndex i = 0; i < numValues; ++i)
 | 
			
		||||
                extensionsArray.add ("." + String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (extensions, i)));
 | 
			
		||||
@ -122,14 +122,14 @@ struct CoreAudioFormatMetatdata
 | 
			
		||||
    static StringPairArray parseUserDefinedChunk (InputStream& input, int64 size)
 | 
			
		||||
    {
 | 
			
		||||
        StringPairArray infoStrings;
 | 
			
		||||
        const int64 originalPosition = input.getPosition();
 | 
			
		||||
        auto originalPosition = input.getPosition();
 | 
			
		||||
 | 
			
		||||
        uint8 uuid[16];
 | 
			
		||||
        input.read (uuid, sizeof (uuid));
 | 
			
		||||
 | 
			
		||||
        if (memcmp (uuid, "\x29\x81\x92\x73\xB5\xBF\x4A\xEF\xB7\x8D\x62\xD1\xEF\x90\xBB\x2C", 16) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            const uint32 numEntries = (uint32) input.readIntBigEndian();
 | 
			
		||||
            auto numEntries = (uint32) input.readIntBigEndian();
 | 
			
		||||
 | 
			
		||||
            for (uint32 i = 0; i < numEntries && input.getPosition() < originalPosition + size; ++i)
 | 
			
		||||
            {
 | 
			
		||||
@ -314,7 +314,7 @@ struct CoreAudioFormatMetatdata
 | 
			
		||||
                    if (chunkHeader.chunkSize == -1)
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    input.skipNextBytes (chunkHeader.chunkSize);
 | 
			
		||||
                    input.setPosition (input.getPosition() + chunkHeader.chunkSize);
 | 
			
		||||
                }
 | 
			
		||||
                else if (chunkHeader.chunkType == chunkName ("midi"))
 | 
			
		||||
                {
 | 
			
		||||
@ -327,7 +327,7 @@ struct CoreAudioFormatMetatdata
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // we aren't decoding this chunk yet so just skip over it
 | 
			
		||||
                    input.skipNextBytes (chunkHeader.chunkSize);
 | 
			
		||||
                    input.setPosition (input.getPosition() + chunkHeader.chunkSize);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -350,13 +350,13 @@ public:
 | 
			
		||||
        if (input != nullptr)
 | 
			
		||||
            CoreAudioFormatMetatdata::read (*input, metadataValues);
 | 
			
		||||
 | 
			
		||||
        OSStatus status = AudioFileOpenWithCallbacks (this,
 | 
			
		||||
                                                      &readCallback,
 | 
			
		||||
                                                      nullptr,  // write needs to be null to avoid permisisions errors
 | 
			
		||||
                                                      &getSizeCallback,
 | 
			
		||||
                                                      nullptr,  // setSize needs to be null to avoid permisisions errors
 | 
			
		||||
                                                      0,        // AudioFileTypeID inFileTypeHint
 | 
			
		||||
                                                      &audioFileID);
 | 
			
		||||
        auto status = AudioFileOpenWithCallbacks (this,
 | 
			
		||||
                                                  &readCallback,
 | 
			
		||||
                                                  nullptr,  // write needs to be null to avoid permisisions errors
 | 
			
		||||
                                                  &getSizeCallback,
 | 
			
		||||
                                                  nullptr,  // setSize needs to be null to avoid permisisions errors
 | 
			
		||||
                                                  0,        // AudioFileTypeID inFileTypeHint
 | 
			
		||||
                                                  &audioFileID);
 | 
			
		||||
        if (status == noErr)
 | 
			
		||||
        {
 | 
			
		||||
            status = ExtAudioFileWrapAudioFileID (audioFileID, false, &audioFileRef);
 | 
			
		||||
@ -447,7 +447,7 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~CoreAudioReader()
 | 
			
		||||
    ~CoreAudioReader() override
 | 
			
		||||
    {
 | 
			
		||||
        ExtAudioFileDispose (audioFileRef);
 | 
			
		||||
        AudioFileClose (audioFileID);
 | 
			
		||||
@ -665,7 +665,7 @@ public:
 | 
			
		||||
            for (auto tagEntry : knownTags)
 | 
			
		||||
                expect (AudioChannelSet::channelSetWithChannels (CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag))
 | 
			
		||||
                            == CoreAudioLayouts::fromCoreAudio (tagEntry.tag),
 | 
			
		||||
                        "Tag \"" + String (tagEntry.name) + "\" is not converted consistantly by JUCE");
 | 
			
		||||
                        "Tag \"" + String (tagEntry.name) + "\" is not converted consistently by JUCE");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ public:
 | 
			
		||||
    CoreAudioFormat();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~CoreAudioFormat();
 | 
			
		||||
    ~CoreAudioFormat() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Metadata property name used when reading a caf file with a MIDI chunk. */
 | 
			
		||||
 | 
			
		||||
@ -117,6 +117,9 @@ namespace FlacNamespace
 | 
			
		||||
  #pragma clang diagnostic ignored "-Wconversion"
 | 
			
		||||
  #pragma clang diagnostic ignored "-Wshadow"
 | 
			
		||||
  #pragma clang diagnostic ignored "-Wdeprecated-register"
 | 
			
		||||
  #if __has_warning("-Wzero-as-null-pointer-constant")
 | 
			
		||||
   #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
 | 
			
		||||
  #endif
 | 
			
		||||
 #endif
 | 
			
		||||
 | 
			
		||||
 #if JUCE_INTEL
 | 
			
		||||
@ -201,7 +204,7 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~FlacReader()
 | 
			
		||||
    ~FlacReader() override
 | 
			
		||||
    {
 | 
			
		||||
        FlacNamespace::FLAC__stream_decoder_delete (decoder);
 | 
			
		||||
    }
 | 
			
		||||
@ -245,7 +248,7 @@ public:
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (startSampleInFile >= (int) lengthInSamples)
 | 
			
		||||
                if (startSampleInFile >= lengthInSamples)
 | 
			
		||||
                {
 | 
			
		||||
                    samplesInReservoir = 0;
 | 
			
		||||
                }
 | 
			
		||||
@ -298,7 +301,7 @@ public:
 | 
			
		||||
                auto* src = buffer[i];
 | 
			
		||||
                int n = i;
 | 
			
		||||
 | 
			
		||||
                while (src == 0 && n > 0)
 | 
			
		||||
                while (src == nullptr && n > 0)
 | 
			
		||||
                    src = buffer [--n];
 | 
			
		||||
 | 
			
		||||
                if (src != nullptr)
 | 
			
		||||
@ -401,7 +404,7 @@ public:
 | 
			
		||||
                                               this) == FlacNamespace::FLAC__STREAM_ENCODER_INIT_STATUS_OK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~FlacWriter()
 | 
			
		||||
    ~FlacWriter() override
 | 
			
		||||
    {
 | 
			
		||||
        if (ok)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ class JUCE_API  FlacAudioFormat    : public AudioFormat
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    FlacAudioFormat();
 | 
			
		||||
    ~FlacAudioFormat();
 | 
			
		||||
    ~FlacAudioFormat() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    Array<int> getPossibleSampleRates() override;
 | 
			
		||||
 | 
			
		||||
@ -1961,8 +1961,8 @@ private:
 | 
			
		||||
            {
 | 
			
		||||
                const uint8 n0 = si.allocation[i][0];
 | 
			
		||||
                const uint8 n1 = si.allocation[i][1];
 | 
			
		||||
                fraction[0][i] = n0 > 0 ? (float) (((-1 << n0) + getBitsUint16 (n0 + 1) + 1) * constants.muls[n0 + 1][si.scaleFactor[i][0]]) : 0;
 | 
			
		||||
                fraction[1][i] = n1 > 0 ? (float) (((-1 << n1) + getBitsUint16 (n1 + 1) + 1) * constants.muls[n1 + 1][si.scaleFactor[i][1]]) : 0;
 | 
			
		||||
                fraction[0][i] = n0 > 0 ? (float) ((-(1 << n0) + getBitsUint16 (n0 + 1) + 1) * constants.muls[n0 + 1][si.scaleFactor[i][0]]) : 0;
 | 
			
		||||
                fraction[1][i] = n1 > 0 ? (float) ((-(1 << n1) + getBitsUint16 (n1 + 1) + 1) * constants.muls[n1 + 1][si.scaleFactor[i][1]]) : 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (i = jsbound; i < 32; ++i)
 | 
			
		||||
@ -1971,7 +1971,7 @@ private:
 | 
			
		||||
 | 
			
		||||
                if (n > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    const uint32 w = ((uint32) (-1 << n) + getBitsUint16 (n + 1) + 1);
 | 
			
		||||
                    const uint32 w = ((uint32) -(1 << n) + getBitsUint16 (n + 1) + 1);
 | 
			
		||||
                    fraction[0][i] = (float) (w * constants.muls[n + 1][si.scaleFactor[i][0]]);
 | 
			
		||||
                    fraction[1][i] = (float) (w * constants.muls[n + 1][si.scaleFactor[i][1]]);
 | 
			
		||||
                }
 | 
			
		||||
@ -1987,7 +1987,7 @@ private:
 | 
			
		||||
                const uint8 j = si.scaleFactor[i][0];
 | 
			
		||||
 | 
			
		||||
                if (n > 0)
 | 
			
		||||
                    fraction[0][i] = (float) (((-1 << n) + getBitsUint16 (n + 1) + 1) * constants.muls[n + 1][j]);
 | 
			
		||||
                    fraction[0][i] = (float) ((-(1 << n) + getBitsUint16 (n + 1) + 1) * constants.muls[n + 1][j]);
 | 
			
		||||
                else
 | 
			
		||||
                    fraction[0][i] = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,9 @@ namespace OggVorbisNamespace
 | 
			
		||||
  #pragma clang diagnostic ignored "-Wconversion"
 | 
			
		||||
  #pragma clang diagnostic ignored "-Wshadow"
 | 
			
		||||
  #pragma clang diagnostic ignored "-Wdeprecated-register"
 | 
			
		||||
  #if __has_warning("-Wzero-as-null-pointer-constant")
 | 
			
		||||
   #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
 | 
			
		||||
  #endif
 | 
			
		||||
 #elif JUCE_GCC
 | 
			
		||||
  #pragma GCC diagnostic push
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wshadow"
 | 
			
		||||
@ -121,7 +124,7 @@ public:
 | 
			
		||||
        callbacks.close_func = &oggCloseCallback;
 | 
			
		||||
        callbacks.tell_func  = &oggTellCallback;
 | 
			
		||||
 | 
			
		||||
        auto err = ov_open_callbacks (input, &ovFile, 0, 0, callbacks);
 | 
			
		||||
        auto err = ov_open_callbacks (input, &ovFile, nullptr, 0, callbacks);
 | 
			
		||||
 | 
			
		||||
        if (err == 0)
 | 
			
		||||
        {
 | 
			
		||||
@ -146,7 +149,7 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~OggReader()
 | 
			
		||||
    ~OggReader() override
 | 
			
		||||
    {
 | 
			
		||||
        ov_clear (&ovFile);
 | 
			
		||||
    }
 | 
			
		||||
@ -319,7 +322,7 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~OggWriter()
 | 
			
		||||
    ~OggWriter() override
 | 
			
		||||
    {
 | 
			
		||||
        if (ok)
 | 
			
		||||
        {
 | 
			
		||||
@ -377,7 +380,7 @@ public:
 | 
			
		||||
 | 
			
		||||
        while (vorbis_analysis_blockout (&vd, &vb) == 1)
 | 
			
		||||
        {
 | 
			
		||||
            vorbis_analysis (&vb, 0);
 | 
			
		||||
            vorbis_analysis (&vb, nullptr);
 | 
			
		||||
            vorbis_bitrate_addblock (&vb);
 | 
			
		||||
 | 
			
		||||
            while (vorbis_bitrate_flushpacket (&vd, &op))
 | 
			
		||||
@ -486,9 +489,7 @@ int OggVorbisAudioFormat::estimateOggFileQuality (const File& source)
 | 
			
		||||
{
 | 
			
		||||
    if (auto* in = source.createInputStream())
 | 
			
		||||
    {
 | 
			
		||||
        std::unique_ptr<AudioFormatReader> r (createReaderFor (in, true));
 | 
			
		||||
 | 
			
		||||
        if (r != nullptr)
 | 
			
		||||
        if (auto r = std::unique_ptr<AudioFormatReader> (createReaderFor (in, true)))
 | 
			
		||||
        {
 | 
			
		||||
            auto lengthSecs = r->lengthInSamples / r->sampleRate;
 | 
			
		||||
            auto approxBitsPerSecond = (int) (source.getSize() * 8 / lengthSecs);
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ class JUCE_API  OggVorbisAudioFormat  : public AudioFormat
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    OggVorbisAudioFormat();
 | 
			
		||||
    ~OggVorbisAudioFormat();
 | 
			
		||||
    ~OggVorbisAudioFormat() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    Array<int> getPossibleSampleRates() override;
 | 
			
		||||
 | 
			
		||||
@ -849,20 +849,21 @@ namespace WavFileHelpers
 | 
			
		||||
    {
 | 
			
		||||
        static void addToMetadata (StringPairArray& destValues, const String& source)
 | 
			
		||||
        {
 | 
			
		||||
            std::unique_ptr<XmlElement> xml (XmlDocument::parse (source));
 | 
			
		||||
 | 
			
		||||
            if (xml != nullptr && xml->hasTagName ("ebucore:ebuCoreMain"))
 | 
			
		||||
            if (auto xml = parseXML (source))
 | 
			
		||||
            {
 | 
			
		||||
                if (auto* xml2 = xml->getChildByName ("ebucore:coreMetadata"))
 | 
			
		||||
                if (xml->hasTagName ("ebucore:ebuCoreMain"))
 | 
			
		||||
                {
 | 
			
		||||
                    if (auto* xml3 = xml2->getChildByName ("ebucore:identifier"))
 | 
			
		||||
                    if (auto xml2 = xml->getChildByName ("ebucore:coreMetadata"))
 | 
			
		||||
                    {
 | 
			
		||||
                        if (auto* xml4 = xml3->getChildByName ("dc:identifier"))
 | 
			
		||||
                        if (auto xml3 = xml2->getChildByName ("ebucore:identifier"))
 | 
			
		||||
                        {
 | 
			
		||||
                            auto ISRCCode = xml4->getAllSubText().fromFirstOccurrenceOf ("ISRC:", false, true);
 | 
			
		||||
                            if (auto xml4 = xml3->getChildByName ("dc:identifier"))
 | 
			
		||||
                            {
 | 
			
		||||
                                auto ISRCCode = xml4->getAllSubText().fromFirstOccurrenceOf ("ISRC:", false, true);
 | 
			
		||||
 | 
			
		||||
                            if (ISRCCode.isNotEmpty())
 | 
			
		||||
                                destValues.set (WavAudioFormat::ISRC, ISRCCode);
 | 
			
		||||
                                if (ISRCCode.isNotEmpty())
 | 
			
		||||
                                    destValues.set (WavAudioFormat::ISRC, ISRCCode);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -1318,7 +1319,7 @@ public:
 | 
			
		||||
        writeHeader();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~WavAudioFormatWriter()
 | 
			
		||||
    ~WavAudioFormatWriter() override
 | 
			
		||||
    {
 | 
			
		||||
        writeHeader();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ public:
 | 
			
		||||
    WavAudioFormat();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~WavAudioFormat();
 | 
			
		||||
    ~WavAudioFormat() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    // BWAV chunk properties:
 | 
			
		||||
 | 
			
		||||
@ -329,11 +329,11 @@ long oggpack_read(oggpack_buffer *b,int bits){
 | 
			
		||||
  if(bits>8){
 | 
			
		||||
    ret|=b->ptr[1]<<(8-b->endbit);
 | 
			
		||||
    if(bits>16){
 | 
			
		||||
      ret|=b->ptr[2]<<(16-b->endbit);
 | 
			
		||||
      ret|=((unsigned long) b->ptr[2]) << (16 - b->endbit);
 | 
			
		||||
      if(bits>24){
 | 
			
		||||
	ret|=b->ptr[3]<<(24-b->endbit);
 | 
			
		||||
	ret |= ((unsigned long) b->ptr[3]) << (24 - b->endbit);
 | 
			
		||||
	if(bits>32 && b->endbit){
 | 
			
		||||
	  ret|=b->ptr[4]<<(32-b->endbit);
 | 
			
		||||
	  ret |= ((unsigned long) b->ptr[4]) << (32 - b->endbit);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1949,7 +1949,7 @@ long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
 | 
			
		||||
            vorbis_fpu_setround(&fpu);
 | 
			
		||||
            for(i=0;i<channels;i++) { /* It's faster in this order */
 | 
			
		||||
              float *src=pcm[i];
 | 
			
		||||
              short *dest=((short *)buffer)+i;
 | 
			
		||||
              short *dest=(reinterpret_cast<short*> (buffer))+i;
 | 
			
		||||
              for(j=0;j<samples;j++) {
 | 
			
		||||
                val=vorbis_ftoi(src[j]*32768.f);
 | 
			
		||||
                if(val>32767)val=32767;
 | 
			
		||||
@ -1965,7 +1965,7 @@ long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
 | 
			
		||||
            vorbis_fpu_setround(&fpu);
 | 
			
		||||
            for(i=0;i<channels;i++) {
 | 
			
		||||
              float *src=pcm[i];
 | 
			
		||||
              short *dest=((short *)buffer)+i;
 | 
			
		||||
              short *dest=(reinterpret_cast<short*> (buffer))+i;
 | 
			
		||||
              for(j=0;j<samples;j++) {
 | 
			
		||||
                val=vorbis_ftoi(src[j]*32768.f);
 | 
			
		||||
                if(val>32767)val=32767;
 | 
			
		||||
 | 
			
		||||
@ -37,24 +37,45 @@ AudioFormatReader::~AudioFormatReader()
 | 
			
		||||
    delete input;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AudioFormatReader::read (int* const* destSamples,
 | 
			
		||||
static void convertFixedToFloat (int* const* channels, int numChannels, int numSamples)
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < numChannels; ++i)
 | 
			
		||||
        if (auto d = channels[i])
 | 
			
		||||
            FloatVectorOperations::convertFixedToFloat (reinterpret_cast<float*> (d), d, 1.0f / 0x7fffffff, numSamples);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AudioFormatReader::read (float* const* destChannels, int numDestChannels,
 | 
			
		||||
                              int64 startSampleInSource, int numSamplesToRead)
 | 
			
		||||
{
 | 
			
		||||
    auto channelsAsInt = reinterpret_cast<int* const*> (destChannels);
 | 
			
		||||
 | 
			
		||||
    if (! read (channelsAsInt, numDestChannels, startSampleInSource, numSamplesToRead, false))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    if (! usesFloatingPointData)
 | 
			
		||||
        convertFixedToFloat (channelsAsInt, numDestChannels, numSamplesToRead);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AudioFormatReader::read (int* const* destChannels,
 | 
			
		||||
                              int numDestChannels,
 | 
			
		||||
                              int64 startSampleInSource,
 | 
			
		||||
                              int numSamplesToRead,
 | 
			
		||||
                              const bool fillLeftoverChannelsWithCopies)
 | 
			
		||||
                              bool fillLeftoverChannelsWithCopies)
 | 
			
		||||
{
 | 
			
		||||
    jassert (numDestChannels > 0); // you have to actually give this some channels to work with!
 | 
			
		||||
 | 
			
		||||
    const size_t originalNumSamplesToRead = (size_t) numSamplesToRead;
 | 
			
		||||
    auto originalNumSamplesToRead = (size_t) numSamplesToRead;
 | 
			
		||||
    int startOffsetInDestBuffer = 0;
 | 
			
		||||
 | 
			
		||||
    if (startSampleInSource < 0)
 | 
			
		||||
    {
 | 
			
		||||
        const int silence = (int) jmin (-startSampleInSource, (int64) numSamplesToRead);
 | 
			
		||||
        auto silence = (int) jmin (-startSampleInSource, (int64) numSamplesToRead);
 | 
			
		||||
 | 
			
		||||
        for (int i = numDestChannels; --i >= 0;)
 | 
			
		||||
            if (destSamples[i] != nullptr)
 | 
			
		||||
                zeromem (destSamples[i], sizeof (int) * (size_t) silence);
 | 
			
		||||
            if (auto d = destChannels[i])
 | 
			
		||||
                zeromem (d, sizeof (int) * (size_t) silence);
 | 
			
		||||
 | 
			
		||||
        startOffsetInDestBuffer += silence;
 | 
			
		||||
        numSamplesToRead -= silence;
 | 
			
		||||
@ -64,7 +85,7 @@ bool AudioFormatReader::read (int* const* destSamples,
 | 
			
		||||
    if (numSamplesToRead <= 0)
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
    if (! readSamples (const_cast<int**> (destSamples),
 | 
			
		||||
    if (! readSamples (const_cast<int**> (destChannels),
 | 
			
		||||
                       jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer,
 | 
			
		||||
                       startSampleInSource, numSamplesToRead))
 | 
			
		||||
        return false;
 | 
			
		||||
@ -73,27 +94,27 @@ bool AudioFormatReader::read (int* const* destSamples,
 | 
			
		||||
    {
 | 
			
		||||
        if (fillLeftoverChannelsWithCopies)
 | 
			
		||||
        {
 | 
			
		||||
            int* lastFullChannel = destSamples[0];
 | 
			
		||||
            auto lastFullChannel = destChannels[0];
 | 
			
		||||
 | 
			
		||||
            for (int i = (int) numChannels; --i > 0;)
 | 
			
		||||
            {
 | 
			
		||||
                if (destSamples[i] != nullptr)
 | 
			
		||||
                if (destChannels[i] != nullptr)
 | 
			
		||||
                {
 | 
			
		||||
                    lastFullChannel = destSamples[i];
 | 
			
		||||
                    lastFullChannel = destChannels[i];
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (lastFullChannel != nullptr)
 | 
			
		||||
                for (int i = (int) numChannels; i < numDestChannels; ++i)
 | 
			
		||||
                    if (destSamples[i] != nullptr)
 | 
			
		||||
                        memcpy (destSamples[i], lastFullChannel, sizeof (int) * originalNumSamplesToRead);
 | 
			
		||||
                    if (auto d = destChannels[i])
 | 
			
		||||
                        memcpy (d, lastFullChannel, sizeof (int) * originalNumSamplesToRead);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = (int) numChannels; i < numDestChannels; ++i)
 | 
			
		||||
                if (destSamples[i] != nullptr)
 | 
			
		||||
                    zeromem (destSamples[i], sizeof (int) * originalNumSamplesToRead);
 | 
			
		||||
                if (auto d = destChannels[i])
 | 
			
		||||
                    zeromem (d, sizeof (int) * originalNumSamplesToRead);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -101,13 +122,17 @@ bool AudioFormatReader::read (int* const* destSamples,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void readChannels (AudioFormatReader& reader, int** chans, AudioBuffer<float>* buffer,
 | 
			
		||||
                          int startSample, int numSamples, int64 readerStartSample, int numTargetChannels)
 | 
			
		||||
                          int startSample, int numSamples, int64 readerStartSample, int numTargetChannels,
 | 
			
		||||
                          bool convertToFloat)
 | 
			
		||||
{
 | 
			
		||||
    for (int j = 0; j < numTargetChannels; ++j)
 | 
			
		||||
        chans[j] = reinterpret_cast<int*> (buffer->getWritePointer (j, startSample));
 | 
			
		||||
 | 
			
		||||
    chans[numTargetChannels] = nullptr;
 | 
			
		||||
    reader.read (chans, numTargetChannels, readerStartSample, numSamples, true);
 | 
			
		||||
 | 
			
		||||
    if (convertToFloat)
 | 
			
		||||
        convertFixedToFloat (chans, numTargetChannels, numSamples);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AudioFormatReader::read (AudioBuffer<float>* buffer,
 | 
			
		||||
@ -122,52 +147,51 @@ void AudioFormatReader::read (AudioBuffer<float>* buffer,
 | 
			
		||||
 | 
			
		||||
    if (numSamples > 0)
 | 
			
		||||
    {
 | 
			
		||||
        const int numTargetChannels = buffer->getNumChannels();
 | 
			
		||||
        auto numTargetChannels = buffer->getNumChannels();
 | 
			
		||||
 | 
			
		||||
        if (numTargetChannels <= 2)
 | 
			
		||||
        {
 | 
			
		||||
            int* const dest0 = reinterpret_cast<int*> (buffer->getWritePointer (0, startSample));
 | 
			
		||||
            int* const dest1 = reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr);
 | 
			
		||||
            int* chans[3];
 | 
			
		||||
            int* dests[2] = { reinterpret_cast<int*> (buffer->getWritePointer (0, startSample)),
 | 
			
		||||
                              reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr) };
 | 
			
		||||
            int* chans[3] = {};
 | 
			
		||||
 | 
			
		||||
            if (useReaderLeftChan == useReaderRightChan)
 | 
			
		||||
            {
 | 
			
		||||
                chans[0] = dest0;
 | 
			
		||||
                chans[1] = numChannels > 1 ? dest1 : nullptr;
 | 
			
		||||
                chans[0] = dests[0];
 | 
			
		||||
 | 
			
		||||
                if (numChannels > 1)
 | 
			
		||||
                    chans[1] = dests[1];
 | 
			
		||||
            }
 | 
			
		||||
            else if (useReaderLeftChan || (numChannels == 1))
 | 
			
		||||
            {
 | 
			
		||||
                chans[0] = dest0;
 | 
			
		||||
                chans[1] = nullptr;
 | 
			
		||||
                chans[0] = dests[0];
 | 
			
		||||
            }
 | 
			
		||||
            else if (useReaderRightChan)
 | 
			
		||||
            {
 | 
			
		||||
                chans[0] = nullptr;
 | 
			
		||||
                chans[1] = dest0;
 | 
			
		||||
                chans[1] = dests[0];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chans[2] = nullptr;
 | 
			
		||||
            read (chans, 2, readerStartSample, numSamples, true);
 | 
			
		||||
 | 
			
		||||
            // if the target's stereo and the source is mono, dupe the first channel..
 | 
			
		||||
            if (numTargetChannels > 1 && (chans[0] == nullptr || chans[1] == nullptr))
 | 
			
		||||
                memcpy (dest1, dest0, sizeof (float) * (size_t) numSamples);
 | 
			
		||||
                memcpy (dests[1], dests[0], sizeof (float) * (size_t) numSamples);
 | 
			
		||||
 | 
			
		||||
            if (! usesFloatingPointData)
 | 
			
		||||
                convertFixedToFloat (dests, 2, numSamples);
 | 
			
		||||
        }
 | 
			
		||||
        else if (numTargetChannels <= 64)
 | 
			
		||||
        {
 | 
			
		||||
            int* chans[65];
 | 
			
		||||
            readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels);
 | 
			
		||||
            readChannels (*this, chans, buffer, startSample, numSamples,
 | 
			
		||||
                          readerStartSample, numTargetChannels, ! usesFloatingPointData);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            HeapBlock<int*> chans (numTargetChannels + 1);
 | 
			
		||||
            readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels);
 | 
			
		||||
            readChannels (*this, chans, buffer, startSample, numSamples,
 | 
			
		||||
                          readerStartSample, numTargetChannels, ! usesFloatingPointData);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (! usesFloatingPointData)
 | 
			
		||||
            for (int j = 0; j < numTargetChannels; ++j)
 | 
			
		||||
                if (float* const d = buffer->getWritePointer (j, startSample))
 | 
			
		||||
                    FloatVectorOperations::convertFixedToFloat (d, reinterpret_cast<const int*> (d), 1.0f / 0x7fffffff, numSamples);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -257,10 +281,9 @@ int64 AudioFormatReader::searchForLevel (int64 startSample,
 | 
			
		||||
    const int bufferSize = 4096;
 | 
			
		||||
    HeapBlock<int> tempSpace (bufferSize * 2 + 64);
 | 
			
		||||
 | 
			
		||||
    int* tempBuffer[3];
 | 
			
		||||
    tempBuffer[0] = tempSpace.get();
 | 
			
		||||
    tempBuffer[1] = tempSpace.get() + bufferSize;
 | 
			
		||||
    tempBuffer[2] = 0;
 | 
			
		||||
    int* tempBuffer[3] = { tempSpace.get(),
 | 
			
		||||
                           tempSpace.get() + bufferSize,
 | 
			
		||||
                           nullptr };
 | 
			
		||||
 | 
			
		||||
    int consecutive = 0;
 | 
			
		||||
    int64 firstMatchPos = -1;
 | 
			
		||||
@ -280,7 +303,7 @@ int64 AudioFormatReader::searchForLevel (int64 startSample,
 | 
			
		||||
        if (numSamplesToSearch < 0)
 | 
			
		||||
            bufferStart -= numThisTime;
 | 
			
		||||
 | 
			
		||||
        if (bufferStart >= (int) lengthInSamples)
 | 
			
		||||
        if (bufferStart >= lengthInSamples)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        read (tempBuffer, 2, bufferStart, numThisTime, false);
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,28 @@ public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Reads samples from the stream.
 | 
			
		||||
 | 
			
		||||
        @param destSamples          an array of buffers into which the sample data for each
 | 
			
		||||
        @param destChannels         an array of float buffers into which the sample data for each
 | 
			
		||||
                                    channel will be written. Channels that aren't needed can be null
 | 
			
		||||
        @param numDestChannels      the number of array elements in the destChannels array
 | 
			
		||||
        @param startSampleInSource  the position in the audio file or stream at which the samples
 | 
			
		||||
                                    should be read, as a number of samples from the start of the
 | 
			
		||||
                                    stream. It's ok for this to be beyond the start or end of the
 | 
			
		||||
                                    available data - any samples that are out-of-range will be returned
 | 
			
		||||
                                    as zeros.
 | 
			
		||||
        @param numSamplesToRead     the number of samples to read. If this is greater than the number
 | 
			
		||||
                                    of samples that the file or stream contains. the result will be padded
 | 
			
		||||
                                    with zeros
 | 
			
		||||
        @returns                    true if the operation succeeded, false if there was an error. Note
 | 
			
		||||
                                    that reading sections of data beyond the extent of the stream isn't an
 | 
			
		||||
                                    error - the reader should just return zeros for these regions
 | 
			
		||||
        @see readMaxLevels
 | 
			
		||||
    */
 | 
			
		||||
    bool read (float* const* destChannels, int numDestChannels,
 | 
			
		||||
               int64 startSampleInSource, int numSamplesToRead);
 | 
			
		||||
 | 
			
		||||
    /** Reads samples from the stream.
 | 
			
		||||
 | 
			
		||||
        @param destChannels         an array of buffers into which the sample data for each
 | 
			
		||||
                                    channel will be written.
 | 
			
		||||
                                    If the format is fixed-point, each channel will be written
 | 
			
		||||
                                    as an array of 32-bit signed integers using the full
 | 
			
		||||
@ -79,8 +100,8 @@ public:
 | 
			
		||||
                                    bit-depth. If it is a floating-point format, you should cast
 | 
			
		||||
                                    the resulting array to a (float**) to get the values (in the
 | 
			
		||||
                                    range -1.0 to 1.0 or beyond)
 | 
			
		||||
                                    If the format is stereo, then destSamples[0] is the left channel
 | 
			
		||||
                                    data, and destSamples[1] is the right channel.
 | 
			
		||||
                                    If the format is stereo, then destChannels[0] is the left channel
 | 
			
		||||
                                    data, and destChannels[1] is the right channel.
 | 
			
		||||
                                    The numDestChannels parameter indicates how many pointers this array
 | 
			
		||||
                                    contains, but some of these pointers can be null if you don't want to
 | 
			
		||||
                                    read data for some of the channels
 | 
			
		||||
@ -107,7 +128,7 @@ public:
 | 
			
		||||
                                    error - the reader should just return zeros for these regions
 | 
			
		||||
        @see readMaxLevels
 | 
			
		||||
    */
 | 
			
		||||
    bool read (int* const* destSamples,
 | 
			
		||||
    bool read (int* const* destChannels,
 | 
			
		||||
               int numDestChannels,
 | 
			
		||||
               int64 startSampleInSource,
 | 
			
		||||
               int numSamplesToRead,
 | 
			
		||||
@ -232,18 +253,18 @@ public:
 | 
			
		||||
 | 
			
		||||
        Callers should use read() instead of calling this directly.
 | 
			
		||||
 | 
			
		||||
        @param destSamples  the array of destination buffers to fill. Some of these
 | 
			
		||||
                            pointers may be null
 | 
			
		||||
        @param numDestChannels  the number of items in the destSamples array. This
 | 
			
		||||
                            value is guaranteed not to be greater than the number of
 | 
			
		||||
                            channels that this reader object contains
 | 
			
		||||
        @param startOffsetInDestBuffer      the number of samples from the start of the
 | 
			
		||||
                            dest data at which to begin writing
 | 
			
		||||
        @param startSampleInFile    the number of samples into the source data at which
 | 
			
		||||
                            to begin reading. This value is guaranteed to be >= 0.
 | 
			
		||||
        @param numSamples   the number of samples to read
 | 
			
		||||
        @param destChannels              the array of destination buffers to fill. Some of these
 | 
			
		||||
                                         pointers may be null
 | 
			
		||||
        @param numDestChannels           the number of items in the destChannels array. This
 | 
			
		||||
                                         value is guaranteed not to be greater than the number of
 | 
			
		||||
                                         channels that this reader object contains
 | 
			
		||||
        @param startOffsetInDestBuffer   the number of samples from the start of the
 | 
			
		||||
                                         dest data at which to begin writing
 | 
			
		||||
        @param startSampleInFile         the number of samples into the source data at which
 | 
			
		||||
                                         to begin reading. This value is guaranteed to be >= 0.
 | 
			
		||||
        @param numSamples                the number of samples to read
 | 
			
		||||
    */
 | 
			
		||||
    virtual bool readSamples (int** destSamples,
 | 
			
		||||
    virtual bool readSamples (int** destChannels,
 | 
			
		||||
                              int numDestChannels,
 | 
			
		||||
                              int startOffsetInDestBuffer,
 | 
			
		||||
                              int64 startSampleInFile,
 | 
			
		||||
@ -282,18 +303,18 @@ protected:
 | 
			
		||||
    /** Used by AudioFormatReader subclasses to clear any parts of the data blocks that lie
 | 
			
		||||
        beyond the end of their available length.
 | 
			
		||||
    */
 | 
			
		||||
    static void clearSamplesBeyondAvailableLength (int** destSamples, int numDestChannels,
 | 
			
		||||
    static void clearSamplesBeyondAvailableLength (int** destChannels, int numDestChannels,
 | 
			
		||||
                                                   int startOffsetInDestBuffer, int64 startSampleInFile,
 | 
			
		||||
                                                   int& numSamples, int64 fileLengthInSamples)
 | 
			
		||||
    {
 | 
			
		||||
        jassert (destSamples != nullptr);
 | 
			
		||||
        jassert (destChannels != nullptr);
 | 
			
		||||
        const int64 samplesAvailable = fileLengthInSamples - startSampleInFile;
 | 
			
		||||
 | 
			
		||||
        if (samplesAvailable < numSamples)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = numDestChannels; --i >= 0;)
 | 
			
		||||
                if (destSamples[i] != nullptr)
 | 
			
		||||
                    zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples);
 | 
			
		||||
                if (destChannels[i] != nullptr)
 | 
			
		||||
                    zeromem (destChannels[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples);
 | 
			
		||||
 | 
			
		||||
            numSamples = (int) samplesAvailable;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,7 @@ public:
 | 
			
		||||
                             bool deleteReaderWhenThisIsDeleted);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~AudioFormatReaderSource();
 | 
			
		||||
    ~AudioFormatReaderSource() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Toggles loop-mode.
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
 | 
			
		||||
    const int bufferSize = 16384;
 | 
			
		||||
    AudioBuffer<float> tempBuffer ((int) numChannels, bufferSize);
 | 
			
		||||
 | 
			
		||||
    int* buffers[128] = { 0 };
 | 
			
		||||
    int* buffers[128] = { nullptr };
 | 
			
		||||
 | 
			
		||||
    for (int i = tempBuffer.getNumChannels(); --i >= 0;)
 | 
			
		||||
        buffers[i] = reinterpret_cast<int*> (tempBuffer.getWritePointer (i, 0));
 | 
			
		||||
@ -222,7 +222,7 @@ public:
 | 
			
		||||
        timeSliceThread.addTimeSliceClient (this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~Buffer()
 | 
			
		||||
    ~Buffer() override
 | 
			
		||||
    {
 | 
			
		||||
        isRunning = false;
 | 
			
		||||
        timeSliceThread.removeTimeSliceClient (this);
 | 
			
		||||
 | 
			
		||||
@ -216,8 +216,8 @@ public:
 | 
			
		||||
        class JUCE_API  IncomingDataReceiver
 | 
			
		||||
        {
 | 
			
		||||
        public:
 | 
			
		||||
            IncomingDataReceiver() {}
 | 
			
		||||
            virtual ~IncomingDataReceiver() {}
 | 
			
		||||
            IncomingDataReceiver() = default;
 | 
			
		||||
            virtual ~IncomingDataReceiver() = default;
 | 
			
		||||
 | 
			
		||||
            virtual void reset (int numChannels, double sampleRate, int64 totalSamplesInSource) = 0;
 | 
			
		||||
            virtual void addBlock (int64 sampleNumberInSource, const AudioBuffer<float>& newData,
 | 
			
		||||
@ -240,7 +240,6 @@ public:
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        class Buffer;
 | 
			
		||||
        friend struct ContainerDeletePolicy<Buffer>;
 | 
			
		||||
        std::unique_ptr<Buffer> buffer;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,16 +27,15 @@
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
AudioSubsectionReader::AudioSubsectionReader (AudioFormatReader* const source_,
 | 
			
		||||
                                              const int64 startSample_,
 | 
			
		||||
                                              const int64 length_,
 | 
			
		||||
                                              const bool deleteSourceWhenDeleted_)
 | 
			
		||||
   : AudioFormatReader (0, source_->getFormatName()),
 | 
			
		||||
     source (source_),
 | 
			
		||||
     startSample (startSample_),
 | 
			
		||||
     deleteSourceWhenDeleted (deleteSourceWhenDeleted_)
 | 
			
		||||
AudioSubsectionReader::AudioSubsectionReader (AudioFormatReader* sourceToUse,
 | 
			
		||||
                                              int64 startSampleToUse, int64 lengthToUse,
 | 
			
		||||
                                              bool deleteSource)
 | 
			
		||||
   : AudioFormatReader (nullptr, sourceToUse->getFormatName()),
 | 
			
		||||
     source (sourceToUse),
 | 
			
		||||
     startSample (startSampleToUse),
 | 
			
		||||
     deleteSourceWhenDeleted (deleteSource)
 | 
			
		||||
{
 | 
			
		||||
    length = jmin (jmax ((int64) 0, source->lengthInSamples - startSample), length_);
 | 
			
		||||
    length = jmin (jmax ((int64) 0, source->lengthInSamples - startSample), lengthToUse);
 | 
			
		||||
 | 
			
		||||
    sampleRate = source->sampleRate;
 | 
			
		||||
    bitsPerSample = source->bitsPerSample;
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@ public:
 | 
			
		||||
                           bool deleteSourceWhenDeleted);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~AudioSubsectionReader();
 | 
			
		||||
    ~AudioSubsectionReader() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -32,9 +32,7 @@ BufferingAudioReader::BufferingAudioReader (AudioFormatReader* sourceReader,
 | 
			
		||||
                                            int samplesToBuffer)
 | 
			
		||||
    : AudioFormatReader (nullptr, sourceReader->getFormatName()),
 | 
			
		||||
      source (sourceReader), thread (timeSliceThread),
 | 
			
		||||
      nextReadPosition (0),
 | 
			
		||||
      numBlocks (1 + (samplesToBuffer / samplesPerBlock)),
 | 
			
		||||
      timeoutMs (0)
 | 
			
		||||
      numBlocks (1 + (samplesToBuffer / samplesPerBlock))
 | 
			
		||||
{
 | 
			
		||||
    sampleRate            = source->sampleRate;
 | 
			
		||||
    lengthInSamples       = source->lengthInSamples;
 | 
			
		||||
@ -62,7 +60,7 @@ void BufferingAudioReader::setReadTimeout (int timeoutMilliseconds) noexcept
 | 
			
		||||
bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
 | 
			
		||||
                                        int64 startSampleInFile, int numSamples)
 | 
			
		||||
{
 | 
			
		||||
    const uint32 startTime = Time::getMillisecondCounter();
 | 
			
		||||
    auto startTime = Time::getMillisecondCounter();
 | 
			
		||||
    clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,
 | 
			
		||||
                                       startSampleInFile, numSamples, lengthInSamples);
 | 
			
		||||
 | 
			
		||||
@ -71,14 +69,14 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
 | 
			
		||||
 | 
			
		||||
    while (numSamples > 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (const BufferedBlock* const block = getBlockContaining (startSampleInFile))
 | 
			
		||||
        if (auto block = getBlockContaining (startSampleInFile))
 | 
			
		||||
        {
 | 
			
		||||
            const int offset = (int) (startSampleInFile - block->range.getStart());
 | 
			
		||||
            const int numToDo = jmin (numSamples, (int) (block->range.getEnd() - startSampleInFile));
 | 
			
		||||
            auto offset = (int) (startSampleInFile - block->range.getStart());
 | 
			
		||||
            auto numToDo = jmin (numSamples, (int) (block->range.getEnd() - startSampleInFile));
 | 
			
		||||
 | 
			
		||||
            for (int j = 0; j < numDestChannels; ++j)
 | 
			
		||||
            {
 | 
			
		||||
                if (float* dest = (float*) destSamples[j])
 | 
			
		||||
                if (auto dest = (float*) destSamples[j])
 | 
			
		||||
                {
 | 
			
		||||
                    dest += startOffsetInDestBuffer;
 | 
			
		||||
 | 
			
		||||
@ -98,7 +96,7 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
 | 
			
		||||
            if (timeoutMs >= 0 && Time::getMillisecondCounter() >= startTime + (uint32) timeoutMs)
 | 
			
		||||
            {
 | 
			
		||||
                for (int j = 0; j < numDestChannels; ++j)
 | 
			
		||||
                    if (float* dest = (float*) destSamples[j])
 | 
			
		||||
                    if (auto dest = (float*) destSamples[j])
 | 
			
		||||
                        FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
@ -123,13 +121,9 @@ BufferingAudioReader::BufferedBlock::BufferedBlock (AudioFormatReader& reader, i
 | 
			
		||||
 | 
			
		||||
BufferingAudioReader::BufferedBlock* BufferingAudioReader::getBlockContaining (int64 pos) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    for (int i = blocks.size(); --i >= 0;)
 | 
			
		||||
    {
 | 
			
		||||
        BufferedBlock* const b = blocks.getUnchecked(i);
 | 
			
		||||
 | 
			
		||||
    for (auto* b : blocks)
 | 
			
		||||
        if (b->range.contains (pos))
 | 
			
		||||
            return b;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
@ -141,9 +135,9 @@ int BufferingAudioReader::useTimeSlice()
 | 
			
		||||
 | 
			
		||||
bool BufferingAudioReader::readNextBufferChunk()
 | 
			
		||||
{
 | 
			
		||||
    const int64 pos = nextReadPosition;
 | 
			
		||||
    const int64 startPos = ((pos - 1024) / samplesPerBlock) * samplesPerBlock;
 | 
			
		||||
    const int64 endPos = startPos + numBlocks * samplesPerBlock;
 | 
			
		||||
    auto pos = nextReadPosition.load();
 | 
			
		||||
    auto startPos = ((pos - 1024) / samplesPerBlock) * samplesPerBlock;
 | 
			
		||||
    auto endPos = startPos + numBlocks * samplesPerBlock;
 | 
			
		||||
 | 
			
		||||
    OwnedArray<BufferedBlock> newBlocks;
 | 
			
		||||
 | 
			
		||||
@ -157,7 +151,7 @@ bool BufferingAudioReader::readNextBufferChunk()
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int64 p = startPos; p < endPos; p += samplesPerBlock)
 | 
			
		||||
    for (auto p = startPos; p < endPos; p += samplesPerBlock)
 | 
			
		||||
    {
 | 
			
		||||
        if (getBlockContaining (p) == nullptr)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@ public:
 | 
			
		||||
                          TimeSliceThread& timeSliceThread,
 | 
			
		||||
                          int samplesToBuffer);
 | 
			
		||||
 | 
			
		||||
    ~BufferingAudioReader();
 | 
			
		||||
    ~BufferingAudioReader() override;
 | 
			
		||||
 | 
			
		||||
    /** Sets a number of milliseconds that the reader can block for in its readSamples()
 | 
			
		||||
        method before giving up and returning silence.
 | 
			
		||||
@ -69,9 +69,9 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
    std::unique_ptr<AudioFormatReader> source;
 | 
			
		||||
    TimeSliceThread& thread;
 | 
			
		||||
    int64 nextReadPosition;
 | 
			
		||||
    std::atomic<int64> nextReadPosition { 0 };
 | 
			
		||||
    const int numBlocks;
 | 
			
		||||
    int timeoutMs;
 | 
			
		||||
    int timeoutMs = 0;
 | 
			
		||||
 | 
			
		||||
    enum { samplesPerBlock = 32768 };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@
 | 
			
		||||
 | 
			
		||||
  ID:               juce_audio_formats
 | 
			
		||||
  vendor:           juce
 | 
			
		||||
  version:          5.3.2
 | 
			
		||||
  version:          5.4.3
 | 
			
		||||
  name:             JUCE audio file format codecs
 | 
			
		||||
  description:      Classes for reading and writing various audio file formats.
 | 
			
		||||
  website:          http://www.juce.com/juce
 | 
			
		||||
 | 
			
		||||
@ -48,8 +48,8 @@ SamplerSound::SamplerSound (const String& soundName,
 | 
			
		||||
 | 
			
		||||
        source.read (data.get(), 0, length + 4, 0, true, true);
 | 
			
		||||
 | 
			
		||||
        attackSamples  = roundToInt (attackTimeSecs  * sourceSampleRate);
 | 
			
		||||
        releaseSamples = roundToInt (releaseTimeSecs * sourceSampleRate);
 | 
			
		||||
        params.attack  = static_cast<float> (attackTimeSecs);
 | 
			
		||||
        params.release = static_cast<float> (releaseTimeSecs);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -87,24 +87,10 @@ void SamplerVoice::startNote (int midiNoteNumber, float velocity, SynthesiserSou
 | 
			
		||||
        lgain = velocity;
 | 
			
		||||
        rgain = velocity;
 | 
			
		||||
 | 
			
		||||
        isInAttack = (sound->attackSamples > 0);
 | 
			
		||||
        isInRelease = false;
 | 
			
		||||
        adsr.setSampleRate (sound->sourceSampleRate);
 | 
			
		||||
        adsr.setParameters (sound->params);
 | 
			
		||||
 | 
			
		||||
        if (isInAttack)
 | 
			
		||||
        {
 | 
			
		||||
            attackReleaseLevel = 0.0f;
 | 
			
		||||
            attackDelta = (float) (pitchRatio / sound->attackSamples);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            attackReleaseLevel = 1.0f;
 | 
			
		||||
            attackDelta = 0.0f;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sound->releaseSamples > 0)
 | 
			
		||||
            releaseDelta = (float) (-pitchRatio / sound->releaseSamples);
 | 
			
		||||
        else
 | 
			
		||||
            releaseDelta = -1.0f;
 | 
			
		||||
        adsr.noteOn();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
@ -116,12 +102,12 @@ void SamplerVoice::stopNote (float /*velocity*/, bool allowTailOff)
 | 
			
		||||
{
 | 
			
		||||
    if (allowTailOff)
 | 
			
		||||
    {
 | 
			
		||||
        isInAttack = false;
 | 
			
		||||
        isInRelease = true;
 | 
			
		||||
        adsr.noteOff();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        clearCurrentNote();
 | 
			
		||||
        adsr.reset();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -151,35 +137,10 @@ void SamplerVoice::renderNextBlock (AudioBuffer<float>& outputBuffer, int startS
 | 
			
		||||
            float r = (inR != nullptr) ? (inR[pos] * invAlpha + inR[pos + 1] * alpha)
 | 
			
		||||
                                       : l;
 | 
			
		||||
 | 
			
		||||
            l *= lgain;
 | 
			
		||||
            r *= rgain;
 | 
			
		||||
            auto envelopeValue = adsr.getNextSample();
 | 
			
		||||
 | 
			
		||||
            if (isInAttack)
 | 
			
		||||
            {
 | 
			
		||||
                l *= attackReleaseLevel;
 | 
			
		||||
                r *= attackReleaseLevel;
 | 
			
		||||
 | 
			
		||||
                attackReleaseLevel += attackDelta;
 | 
			
		||||
 | 
			
		||||
                if (attackReleaseLevel >= 1.0f)
 | 
			
		||||
                {
 | 
			
		||||
                    attackReleaseLevel = 1.0f;
 | 
			
		||||
                    isInAttack = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (isInRelease)
 | 
			
		||||
            {
 | 
			
		||||
                l *= attackReleaseLevel;
 | 
			
		||||
                r *= attackReleaseLevel;
 | 
			
		||||
 | 
			
		||||
                attackReleaseLevel += releaseDelta;
 | 
			
		||||
 | 
			
		||||
                if (attackReleaseLevel <= 0.0f)
 | 
			
		||||
                {
 | 
			
		||||
                    stopNote (0.0f, false);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            l *= lgain * envelopeValue;
 | 
			
		||||
            r *= rgain * envelopeValue;
 | 
			
		||||
 | 
			
		||||
            if (outR != nullptr)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
@ -72,7 +72,7 @@ public:
 | 
			
		||||
                  double maxSampleLengthSeconds);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~SamplerSound();
 | 
			
		||||
    ~SamplerSound() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the sample's name */
 | 
			
		||||
@ -83,12 +83,14 @@ public:
 | 
			
		||||
    */
 | 
			
		||||
    AudioBuffer<float>* getAudioData() const noexcept       { return data.get(); }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Changes the parameters of the ADSR envelope which will be applied to the sample. */
 | 
			
		||||
    void setEnvelopeParameters (ADSR::Parameters parametersToUse)    { params = parametersToUse; }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    bool appliesToNote (int midiNoteNumber) override;
 | 
			
		||||
    bool appliesToChannel (int midiChannel) override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    friend class SamplerVoice;
 | 
			
		||||
@ -97,8 +99,9 @@ private:
 | 
			
		||||
    std::unique_ptr<AudioBuffer<float>> data;
 | 
			
		||||
    double sourceSampleRate;
 | 
			
		||||
    BigInteger midiNotes;
 | 
			
		||||
    int length = 0, attackSamples = 0, releaseSamples = 0;
 | 
			
		||||
    int midiRootNote = 0;
 | 
			
		||||
    int length = 0, midiRootNote = 0;
 | 
			
		||||
 | 
			
		||||
    ADSR::Parameters params;
 | 
			
		||||
 | 
			
		||||
    JUCE_LEAK_DETECTOR (SamplerSound)
 | 
			
		||||
};
 | 
			
		||||
@ -123,7 +126,7 @@ public:
 | 
			
		||||
    SamplerVoice();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~SamplerVoice();
 | 
			
		||||
    ~SamplerVoice() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    bool canPlaySound (SynthesiserSound*) override;
 | 
			
		||||
@ -136,13 +139,13 @@ public:
 | 
			
		||||
 | 
			
		||||
    void renderNextBlock (AudioBuffer<float>&, int startSample, int numSamples) override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    double pitchRatio = 0;
 | 
			
		||||
    double sourceSamplePosition = 0;
 | 
			
		||||
    float lgain = 0, rgain = 0, attackReleaseLevel = 0, attackDelta = 0, releaseDelta = 0;
 | 
			
		||||
    bool isInAttack = false, isInRelease = false;
 | 
			
		||||
    float lgain = 0, rgain = 0;
 | 
			
		||||
 | 
			
		||||
    ADSR adsr;
 | 
			
		||||
 | 
			
		||||
    JUCE_LEAK_DETECTOR (SamplerVoice)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user