void MidiMessageSequence::deleteEvent (const int index, const bool deleteMatchingNoteUp) { if (isPositiveAndBelow (index, list.size())) { if (deleteMatchingNoteUp) deleteEvent (getIndexOfMatchingKeyUp (index), false); list.remove (index); } }
float AudioSampleBuffer::getMagnitude (const int channel, const int startSample, const int numSamples) const noexcept { jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); float mn, mx; findMinMax (channel, startSample, numSamples, mn, mx); return jmax (mn, -mn, mx, -mx); }
void setParameter (int index, float newValue) { if (plugin != nullptr && isPositiveAndBelow (index, parameters.size())) { const ScopedLock sl (lock); ParameterValue& p = parameterValues[index]; if (p.unscaled != newValue) p = ParameterValue (getNewParamScaled (plugin->PortRangeHints [parameters[index]], newValue), newValue); } }
const Colour Image::BitmapData::getPixelColour (const int x, const int y) const noexcept { jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height)); const uint8* const pixel = getPixelPointer (x, y); switch (pixelFormat) { case Image::ARGB: return Colour (((const PixelARGB*) pixel)->getUnpremultipliedARGB()); case Image::RGB: return Colour (((const PixelRGB*) pixel)->getUnpremultipliedARGB()); case Image::SingleChannel: return Colour (((const PixelAlpha*) pixel)->getUnpremultipliedARGB()); default: jassertfalse; break; } return Colour(); }
Range<float> AudioSampleBuffer::findMinMax (const int channel, const int startSample, int numSamples) const noexcept { jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); if (isClear) return Range<float>(); return FloatVectorOperations::findMinAndMax (channels [channel] + startSample, numSamples); }
void moveChild (int currentIndex, int newIndex, UndoManager* undoManager) { // The source index must be a valid index! jassert (isPositiveAndBelow (currentIndex, children.size())); if (currentIndex != newIndex && isPositiveAndBelow (currentIndex, children.size())) { if (undoManager == nullptr) { children.move (currentIndex, newIndex); sendChildOrderChangedMessage (currentIndex, newIndex); } else { if (! isPositiveAndBelow (newIndex, children.size())) newIndex = children.size() - 1; undoManager->perform (new MoveChildAction (*this, currentIndex, newIndex)); } } }
void SequenceCursor::updateTrack (const SequencerTrack* track) { const int32 index = track->index(); if (isPositiveAndBelow (index, trackCount.get())) { ClipSource* clip = seekClip (track, nullptr, mFrame); if (clip && clip->isInRangeOf (mFrame)) clip->seekLocalFrame (mFrame - clip->frameStart()); rtClips [index] = clip; } }
void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoManager* undoManager) { // The source index must be a valid index! jassert (isPositiveAndBelow (currentIndex, children.size())); if (currentIndex != newIndex && isPositiveAndBelow (currentIndex, children.size())) { if (undoManager == 0) { children.move (currentIndex, newIndex); sendChildChangeMessage(); } else { if (! isPositiveAndBelow (newIndex, children.size())) newIndex = children.size() - 1; undoManager->perform (new MoveChildAction (this, currentIndex, newIndex)); } } }
void AudioProcessor::sendParamChangeMessageToListeners (const int parameterIndex, const float newValue) { if (isPositiveAndBelow (parameterIndex, getNumParameters())) { for (int i = listeners.size(); --i >= 0;) if (AudioProcessorListener* l = getListenerLocked (i)) l->audioProcessorParameterChanged (this, parameterIndex, newValue); } else { jassertfalse; // called with an out-of-range parameter index! } }
bool TabBarButton::hitTest (int mx, int my) { const Rectangle<int> area (getActiveArea()); if (owner.isVertical()) { if (isPositiveAndBelow (mx, getWidth()) && my >= area.getY() + overlapPixels && my < area.getBottom() - overlapPixels) return true; } else { if (isPositiveAndBelow (my, getHeight()) && mx >= area.getX() + overlapPixels && mx < area.getRight() - overlapPixels) return true; } Path p; getLookAndFeel().createTabButtonShape (*this, p, false, false); return p.contains ((float) (mx - area.getX()), (float) (my - area.getY())); }
float AudioSampleBuffer::getMagnitude (const int channel, const int startSample, const int numSamples) const noexcept { jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); if (isClear) return 0.0f; const Range<float> r (findMinMax (channel, startSample, numSamples)); return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd()); }
void Image::BitmapData::setPixelColour (const int x, const int y, const Colour& colour) const noexcept { jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height)); uint8* const pixel = getPixelPointer (x, y); const PixelARGB col (colour.getPixelARGB()); switch (pixelFormat) { case Image::ARGB: ((PixelARGB*) pixel)->set (col); break; case Image::RGB: ((PixelRGB*) pixel)->set (col); break; case Image::SingleChannel: *pixel = col.getAlpha(); break; default: jassertfalse; break; } }
//============================================================================== void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected) override { Rectangle<int> bounds (0, 0, width, height); auto textColour = findColour (Label::textColourId); g.setColour (textColour.withAlpha (0.4f)); if (rowNumber == 0) g.fillRect (bounds.removeFromTop (2).reduced (7, 0)); g.fillRect (bounds.removeFromBottom (2).reduced (7, 0)); if (rowIsSelected) { g.setColour (findColour (TextEditor::highlightColourId).withAlpha (0.4f)); g.fillRect (bounds); textColour = findColour (TextEditor::highlightedTextColourId); } g.setColour (textColour); if (selectedCategory.isEmpty()) { if (isPositiveAndBelow (rowNumber, JUCEDemos::getCategories().size())) g.drawFittedText (JUCEDemos::getCategories()[rowNumber].name, bounds, Justification::centred, 1); } else { auto& category = JUCEDemos::getCategory (selectedCategory); if (isPositiveAndBelow (rowNumber, category.demos.size())) g.drawFittedText (category.demos[rowNumber].demoFile.getFileName(), bounds, Justification::centred, 1); } }
void AudioSampleBuffer::addFrom (const int destChannel, const int destStartSample, const AudioSampleBuffer& source, const int sourceChannel, const int sourceStartSample, int numSamples, const float gain) noexcept { jassert (&source != this || sourceChannel != destChannel); jassert (isPositiveAndBelow (destChannel, numChannels)); jassert (destStartSample >= 0 && destStartSample + numSamples <= size); jassert (isPositiveAndBelow (sourceChannel, source.numChannels)); jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); if (gain != 0.0f && numSamples > 0 && ! source.isClear) { float* const d = channels [destChannel] + destStartSample; const float* const s = source.channels [sourceChannel] + sourceStartSample; if (isClear) { isClear = false; if (gain != 1.0f) FloatVectorOperations::copyWithMultiply (d, s, gain, numSamples); else FloatVectorOperations::copy (d, s, numSamples); } else { if (gain != 1.0f) FloatVectorOperations::addWithMultiply (d, s, gain, numSamples); else FloatVectorOperations::add (d, s, numSamples); } } }
void AudioProcessor::beginParameterChangeGesture (int parameterIndex) { jassert (isPositiveAndBelow (parameterIndex, getNumParameters())); #if JUCE_DEBUG // This means you've called beginParameterChangeGesture twice in succession without a matching // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it. jassert (! changingParams [parameterIndex]); changingParams.setBit (parameterIndex); #endif for (int i = listeners.size(); --i >= 0;) if (AudioProcessorListener* l = getListenerLocked (i)) l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); }
void AudioSampleBuffer::copyFrom (const int destChannel, const int destStartSample, const float* source, int numSamples) noexcept { jassert (isPositiveAndBelow (destChannel, numChannels)); jassert (destStartSample >= 0 && destStartSample + numSamples <= size); jassert (source != nullptr); if (numSamples > 0) { isClear = false; FloatVectorOperations::copy (channels [destChannel] + destStartSample, source, numSamples); } }
static SharedCursorHandle* createStandard (const MouseCursor::StandardCursorType type) { jassert (isPositiveAndBelow (type, MouseCursor::NumStandardCursorTypes)); const SpinLock::ScopedLockType sl (lock); SharedCursorHandle*& c = getSharedCursor (type); if (c == nullptr) c = new SharedCursorHandle (type); else c->retain(); return c; }
void AudioSampleBuffer::copyFrom (const int destChannel, const int destStartSample, const float* source, int numSamples) noexcept { jassert (isPositiveAndBelow (destChannel, numChannels)); jassert (destStartSample >= 0 && destStartSample + numSamples <= size); jassert (source != nullptr); if (numSamples > 0) { memcpy (channels [destChannel] + destStartSample, source, sizeof (float) * (size_t) numSamples); } }
void handleGUIEditorMenuCommand (int menuItemID) { if (JucerDocumentEditor* ed = JucerDocumentEditor::getActiveDocumentHolder()) { int gridIndex = menuItemID - gridSnapMenuItemBase; if (isPositiveAndBelow (gridIndex, numElementsInArray (snapSizes))) { JucerDocument& doc = *ed->getDocument(); doc.setSnappingGrid (snapSizes [gridIndex], doc.isSnapActive (false), doc.isSnapShown()); } } }
void AudioProcessor::endParameterChangeGesture (int parameterIndex) { jassert (isPositiveAndBelow (parameterIndex, getNumParameters())); #if JUCE_DEBUG // This means you've called endParameterChangeGesture without having previously called // endParameterChangeGesture. That might be fine in most hosts, but better to keep the // calls matched correctly. jassert (changingParams [parameterIndex]); changingParams.clearBit (parameterIndex); #endif for (int i = listeners.size(); --i >= 0;) if (AudioProcessorListener* l = getListenerLocked (i)) l->audioProcessorParameterChangeGestureEnd (this, parameterIndex); }
void TreeViewItem::removeSubItem (const int index, const bool deleteItem) { if (ownerView != 0) { const ScopedLock sl (ownerView->nodeAlterationLock); if (isPositiveAndBelow (index, subItems.size())) { subItems.remove (index, deleteItem); treeHasChanged(); } } else { subItems.remove (index, deleteItem); } }
void AudioProcessor::sendParamChangeMessageToListeners (const int parameterIndex, const float newValue) { jassert (isPositiveAndBelow (parameterIndex, getNumParameters())); for (int i = listeners.size(); --i >= 0;) { AudioProcessorListener* l; { const ScopedLock sl (listenerLock); l = listeners [i]; } if (l != nullptr) l->audioProcessorParameterChanged (this, parameterIndex, newValue); } }
Oversampling<SampleType>::Oversampling (size_t newNumChannels, size_t newFactor, FilterType newType, bool isMaximumQuality) : numChannels (newNumChannels) { jassert (isPositiveAndBelow (newFactor, 5) && numChannels > 0); if (newFactor == 0) { addDummyOversamplingStage(); } else if (newType == FilterType::filterHalfBandPolyphaseIIR) { for (size_t n = 0; n < newFactor; ++n) { auto twUp = (isMaximumQuality ? 0.10f : 0.12f) * (n == 0 ? 0.5f : 1.0f); auto twDown = (isMaximumQuality ? 0.12f : 0.15f) * (n == 0 ? 0.5f : 1.0f); auto gaindBStartUp = (isMaximumQuality ? -90.0f : -70.0f); auto gaindBStartDown = (isMaximumQuality ? -75.0f : -60.0f); auto gaindBFactorUp = (isMaximumQuality ? 10.0f : 8.0f); auto gaindBFactorDown = (isMaximumQuality ? 10.0f : 8.0f); addOversamplingStage (FilterType::filterHalfBandPolyphaseIIR, twUp, gaindBStartUp + gaindBFactorUp * n, twDown, gaindBStartDown + gaindBFactorDown * n); } } else if (newType == FilterType::filterHalfBandFIREquiripple) { for (size_t n = 0; n < newFactor; ++n) { auto twUp = (isMaximumQuality ? 0.10f : 0.12f) * (n == 0 ? 0.5f : 1.0f); auto twDown = (isMaximumQuality ? 0.12f : 0.15f) * (n == 0 ? 0.5f : 1.0f); auto gaindBStartUp = (isMaximumQuality ? -90.0f : -70.0f); auto gaindBStartDown = (isMaximumQuality ? -75.0f : -60.0f); auto gaindBFactorUp = (isMaximumQuality ? 10.0f : 8.0f); auto gaindBFactorDown = (isMaximumQuality ? 10.0f : 8.0f); addOversamplingStage (FilterType::filterHalfBandFIREquiripple, twUp, gaindBStartUp + gaindBFactorUp * n, twDown, gaindBStartDown + gaindBFactorDown * n); } } }
void AudioSampleBuffer::applyGain (const int channel, const int startSample, int numSamples, const float gain) noexcept { jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); if (gain != 1.0f && ! isClear) { float* const d = channels [channel] + startSample; if (gain == 0.0f) FloatVectorOperations::clear (d, numSamples); else FloatVectorOperations::multiply (d, gain, numSamples); } }
void drawChannel (Graphics& g, const Rectangle<int>& area, const double startTime, const double endTime, const int channelNum, const float verticalZoomFactor, const double rate, const int numChans, const int sampsPerThumbSample, LevelDataSource* levelData, const OwnedArray<ThumbData>& chans) { if (refillCache (area.getWidth(), startTime, endTime, rate, numChans, sampsPerThumbSample, levelData, chans) && isPositiveAndBelow (channelNum, numChannelsCached)) { const Rectangle<int> clip (g.getClipBounds().getIntersection (area.withWidth (jmin (numSamplesCached, area.getWidth())))); if (! clip.isEmpty()) { const float topY = (float) area.getY(); const float bottomY = (float) area.getBottom(); const float midY = (topY + bottomY) * 0.5f; const float vscale = verticalZoomFactor * (bottomY - topY) / 256.0f; const MinMaxValue* cacheData = getData (channelNum, clip.getX() - area.getX()); RectangleList<float> waveform; waveform.ensureStorageAllocated (clip.getWidth()); float x = (float) clip.getX(); for (int w = clip.getWidth(); --w >= 0;) { if (cacheData->isNonZero()) { const float top = jmax (midY - cacheData->getMaxValue() * vscale - 0.3f, topY); const float bottom = jmin (midY - cacheData->getMinValue() * vscale + 0.3f, bottomY); waveform.addWithoutMerging (Rectangle<float> (x, top, 1.0f, bottom - top)); } x += 1.0f; ++cacheData; } g.fillRectList (waveform); } } }
void setCurrentSourceIndex (int index, bool input) { if (deviceID != 0) { HeapBlock <OSType> types; const int num = getAllDataSourcesForDevice (deviceID, types); if (isPositiveAndBelow (index, num)) { AudioObjectPropertyAddress pa; pa.mSelector = kAudioDevicePropertyDataSource; pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; pa.mElement = kAudioObjectPropertyElementMaster; OSType typeId = types[index]; OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (typeId), &typeId)); } } }
void AudioProcessor::beginParameterChangeGesture (int parameterIndex) { if (isPositiveAndBelow (parameterIndex, getNumParameters())) { #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING // This means you've called beginParameterChangeGesture twice in succession without a matching // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it. jassert (! changingParams [parameterIndex]); changingParams.setBit (parameterIndex); #endif for (int i = listeners.size(); --i >= 0;) if (AudioProcessorListener* l = getListenerLocked (i)) l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); } else { jassertfalse; // called with an out-of-range parameter index! } }
void MidiLogListBoxModel::paintListBoxItem(int row, Graphics& g, int width, int height, bool rowIsSelected) { if (rowIsSelected) g.fillAll(Colours::blue.withAlpha(0.2f)); if (isPositiveAndBelow(row, midiMessageList.size())) { g.setColour(Colours::black); const MidiMessage& message = midiMessageList.getReference(row); double time = message.getTimeStamp(); g.drawText(String::formatted("%02d:%02d:%02d", static_cast<int>(time / 3600.0) % 24, static_cast<int>(time / 60.0) % 60, static_cast<int>(time) % 60) + " - " + ZenMidiVisualiserComponent::getMidiMessageDescription(message), Rectangle<int>(width, height).reduced(4, 0), Justification::centredLeft, true); } }
void AudioProcessor::endParameterChangeGesture (int parameterIndex) { if (isPositiveAndBelow (parameterIndex, getNumParameters())) { #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING // This means you've called endParameterChangeGesture without having previously called // beginParameterChangeGesture. That might be fine in most hosts, but better to keep the // calls matched correctly. jassert (changingParams [parameterIndex]); changingParams.clearBit (parameterIndex); #endif for (int i = listeners.size(); --i >= 0;) if (AudioProcessorListener* l = getListenerLocked (i)) l->audioProcessorParameterChangeGestureEnd (this, parameterIndex); } else { jassertfalse; // called with an out-of-range parameter index! } }
float AudioSampleBuffer::getRMSLevel (const int channel, const int startSample, const int numSamples) const noexcept { jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); if (numSamples <= 0 || channel < 0 || channel >= numChannels) return 0.0f; const float* const data = channels [channel] + startSample; double sum = 0.0; for (int i = 0; i < numSamples; ++i) { const float sample = data [i]; sum += sample * sample; } return (float) std::sqrt (sum / numSamples); }