| @@ -788,7 +788,7 @@ public: | |||||
| AudioEffectX::resume(); | AudioEffectX::resume(); | ||||
| #if JucePlugin_ProducesMidiOutput | #if JucePlugin_ProducesMidiOutput | ||||
| outgoingEvents.ensureSize (64); | |||||
| outgoingEvents.ensureSize (512); | |||||
| #endif | #endif | ||||
| #if JucePlugin_WantsMidiInput && ! JUCE_USE_VSTSDK_2_4 | #if JucePlugin_WantsMidiInput && ! JUCE_USE_VSTSDK_2_4 | ||||
| @@ -287,8 +287,8 @@ private: | |||||
| } | } | ||||
| private: | private: | ||||
| const String attributeToSort; | |||||
| const int direction; | |||||
| String attributeToSort; | |||||
| int direction; | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -877,8 +877,6 @@ private: | |||||
| Drawable* image = iconsFromZipFile [iconNames.indexOf (filename)]->createCopy(); | Drawable* image = iconsFromZipFile [iconNames.indexOf (filename)]->createCopy(); | ||||
| return new ToolbarButton (itemId, text, image, 0); | return new ToolbarButton (itemId, text, image, 0); | ||||
| return 0; | |||||
| } | } | ||||
| // Demonstrates how to put a custom component into a toolbar - this one contains | // Demonstrates how to put a custom component into a toolbar - this one contains | ||||
| @@ -217544,7 +217544,6 @@ namespace ActiveXHelpers | |||||
| HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo) | HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo) | ||||
| { | { | ||||
| // frame->AddRef(); // MS docs are unclear about whether this is needed, but it seems to lead to a memory leak.. | |||||
| *lplpFrame = frame; | *lplpFrame = frame; | ||||
| *lplpDoc = 0; | *lplpDoc = 0; | ||||
| lpFrameInfo->fMDIApp = FALSE; | lpFrameInfo->fMDIApp = FALSE; | ||||
| @@ -217662,7 +217661,7 @@ namespace ActiveXHelpers | |||||
| } | } | ||||
| } | } | ||||
| class ActiveXControlComponent::ActiveXControlData : public ComponentMovementWatcher | |||||
| class ActiveXControlComponent::Pimpl : public ComponentMovementWatcher | |||||
| { | { | ||||
| ActiveXControlComponent* const owner; | ActiveXControlComponent* const owner; | ||||
| bool wasShowing; | bool wasShowing; | ||||
| @@ -217673,8 +217672,7 @@ public: | |||||
| IOleClientSite* clientSite; | IOleClientSite* clientSite; | ||||
| IOleObject* control; | IOleObject* control; | ||||
| ActiveXControlData (HWND hwnd, | |||||
| ActiveXControlComponent* const owner_) | |||||
| Pimpl (HWND hwnd, ActiveXControlComponent* const owner_) | |||||
| : ComponentMovementWatcher (owner_), | : ComponentMovementWatcher (owner_), | ||||
| owner (owner_), | owner (owner_), | ||||
| wasShowing (owner_ != 0 && owner_->isShowing()), | wasShowing (owner_ != 0 && owner_->isShowing()), | ||||
| @@ -217685,7 +217683,7 @@ public: | |||||
| { | { | ||||
| } | } | ||||
| ~ActiveXControlData() | |||||
| ~Pimpl() | |||||
| { | { | ||||
| if (control != 0) | if (control != 0) | ||||
| { | { | ||||
| @@ -217727,20 +217725,15 @@ public: | |||||
| componentPeerChanged(); | componentPeerChanged(); | ||||
| } | } | ||||
| static bool doesWindowMatch (const ActiveXControlComponent* const ax, HWND hwnd) | |||||
| { | |||||
| return ((ActiveXControlData*) ax->control) != 0 | |||||
| && ((ActiveXControlData*) ax->control)->controlHWND == hwnd; | |||||
| } | |||||
| // intercepts events going to an activeX control, so we can sneakily use the mouse events | // intercepts events going to an activeX control, so we can sneakily use the mouse events | ||||
| static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | ||||
| { | { | ||||
| for (int i = ActiveXHelpers::activeXComps.size(); --i >= 0;) | for (int i = ActiveXHelpers::activeXComps.size(); --i >= 0;) | ||||
| { | { | ||||
| const ActiveXControlComponent* const ax = (const ActiveXControlComponent*) ActiveXHelpers::activeXComps.getUnchecked(i); | |||||
| const ActiveXControlComponent* const ax | |||||
| = static_cast <const ActiveXControlComponent*> (ActiveXHelpers::activeXComps.getUnchecked(i)); | |||||
| if (doesWindowMatch (ax, hwnd)) | |||||
| if (ax->control != 0 && ax->control->controlHWND == hwnd) | |||||
| { | { | ||||
| switch (message) | switch (message) | ||||
| { | { | ||||
| @@ -217772,7 +217765,7 @@ public: | |||||
| break; | break; | ||||
| } | } | ||||
| return CallWindowProc ((WNDPROC) (ax->originalWndProc), hwnd, message, wParam, lParam); | |||||
| return CallWindowProc ((WNDPROC) ax->originalWndProc, hwnd, message, wParam, lParam); | |||||
| } | } | ||||
| } | } | ||||
| @@ -217782,7 +217775,6 @@ public: | |||||
| ActiveXControlComponent::ActiveXControlComponent() | ActiveXControlComponent::ActiveXControlComponent() | ||||
| : originalWndProc (0), | : originalWndProc (0), | ||||
| control (0), | |||||
| mouseEventsAllowed (true) | mouseEventsAllowed (true) | ||||
| { | { | ||||
| ActiveXHelpers::activeXComps.add (this); | ActiveXHelpers::activeXComps.add (this); | ||||
| @@ -217813,16 +217805,16 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||||
| const Point<int> pos (relativePositionToOtherComponent (getTopLevelComponent(), Point<int>())); | const Point<int> pos (relativePositionToOtherComponent (getTopLevelComponent(), Point<int>())); | ||||
| HWND hwnd = (HWND) peer->getNativeHandle(); | HWND hwnd = (HWND) peer->getNativeHandle(); | ||||
| ScopedPointer <ActiveXControlData> info (new ActiveXControlData (hwnd, this)); | |||||
| ScopedPointer<Pimpl> newControl (new Pimpl (hwnd, this)); | |||||
| HRESULT hr; | HRESULT hr; | ||||
| if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0, | if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0, | ||||
| info->clientSite, info->storage, | |||||
| (void**) &(info->control))) == S_OK) | |||||
| newControl->clientSite, newControl->storage, | |||||
| (void**) &(newControl->control))) == S_OK) | |||||
| { | { | ||||
| info->control->SetHostNames (L"Juce", 0); | |||||
| newControl->control->SetHostNames (L"Juce", 0); | |||||
| if (OleSetContainedObject (info->control, TRUE) == S_OK) | |||||
| if (OleSetContainedObject (newControl->control, TRUE) == S_OK) | |||||
| { | { | ||||
| RECT rect; | RECT rect; | ||||
| rect.left = pos.getX(); | rect.left = pos.getX(); | ||||
| @@ -217830,17 +217822,17 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||||
| rect.right = pos.getX() + getWidth(); | rect.right = pos.getX() + getWidth(); | ||||
| rect.bottom = pos.getY() + getHeight(); | rect.bottom = pos.getY() + getHeight(); | ||||
| if (info->control->DoVerb (OLEIVERB_SHOW, 0, info->clientSite, 0, hwnd, &rect) == S_OK) | |||||
| if (newControl->control->DoVerb (OLEIVERB_SHOW, 0, newControl->clientSite, 0, hwnd, &rect) == S_OK) | |||||
| { | { | ||||
| control = info.release(); | |||||
| control = newControl; | |||||
| setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); | setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); | ||||
| ((ActiveXControlData*) control)->controlHWND = ActiveXHelpers::getHWND (this); | |||||
| control->controlHWND = ActiveXHelpers::getHWND (this); | |||||
| if (((ActiveXControlData*) control)->controlHWND != 0) | |||||
| if (control->controlHWND != 0) | |||||
| { | { | ||||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC); | |||||
| SetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC, (LONG_PTR) ActiveXControlData::activeXHookWndProc); | |||||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC); | |||||
| SetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC, (LONG_PTR) Pimpl::activeXHookWndProc); | |||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -217854,24 +217846,16 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||||
| void ActiveXControlComponent::deleteControl() | void ActiveXControlComponent::deleteControl() | ||||
| { | { | ||||
| ActiveXControlData* const info = (ActiveXControlData*) control; | |||||
| if (info != 0) | |||||
| { | |||||
| delete info; | |||||
| control = 0; | |||||
| originalWndProc = 0; | |||||
| } | |||||
| control = 0; | |||||
| originalWndProc = 0; | |||||
| } | } | ||||
| void* ActiveXControlComponent::queryInterface (const void* iid) const | void* ActiveXControlComponent::queryInterface (const void* iid) const | ||||
| { | { | ||||
| ActiveXControlData* const info = (ActiveXControlData*) control; | |||||
| void* result = 0; | void* result = 0; | ||||
| if (info != 0 && info->control != 0 | |||||
| && info->control->QueryInterface (*(const IID*) iid, &result) == S_OK) | |||||
| if (control != 0 && control->control != 0 | |||||
| && SUCCEEDED (control->control->QueryInterface (*(const IID*) iid, &result))) | |||||
| return result; | return result; | ||||
| return 0; | return 0; | ||||
| @@ -217879,18 +217863,14 @@ void* ActiveXControlComponent::queryInterface (const void* iid) const | |||||
| void ActiveXControlComponent::setControlBounds (const Rectangle<int>& newBounds) const | void ActiveXControlComponent::setControlBounds (const Rectangle<int>& newBounds) const | ||||
| { | { | ||||
| HWND hwnd = ((ActiveXControlData*) control)->controlHWND; | |||||
| if (hwnd != 0) | |||||
| MoveWindow (hwnd, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); | |||||
| if (control->controlHWND != 0) | |||||
| MoveWindow (control->controlHWND, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); | |||||
| } | } | ||||
| void ActiveXControlComponent::setControlVisible (const bool shouldBeVisible) const | void ActiveXControlComponent::setControlVisible (const bool shouldBeVisible) const | ||||
| { | { | ||||
| HWND hwnd = ((ActiveXControlData*) control)->controlHWND; | |||||
| if (hwnd != 0) | |||||
| ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE); | |||||
| if (control->controlHWND != 0) | |||||
| ShowWindow (control->controlHWND, shouldBeVisible ? SW_SHOWNA : SW_HIDE); | |||||
| } | } | ||||
| void ActiveXControlComponent::setMouseEventsAllowed (const bool eventsCanReachControl) | void ActiveXControlComponent::setMouseEventsAllowed (const bool eventsCanReachControl) | ||||
| @@ -225858,8 +225838,7 @@ public: | |||||
| minBufferSize = wasapi_refTimeToSamples (minPeriod, defaultSampleRate); | minBufferSize = wasapi_refTimeToSamples (minPeriod, defaultSampleRate); | ||||
| defaultBufferSize = wasapi_refTimeToSamples (defaultPeriod, defaultSampleRate); | defaultBufferSize = wasapi_refTimeToSamples (defaultPeriod, defaultSampleRate); | ||||
| FloatElementComparator<double> comparator; | |||||
| rates.addSorted (comparator, defaultSampleRate); | |||||
| rates.addUsingDefaultSort (defaultSampleRate); | |||||
| static const double ratesToTest[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; | static const double ratesToTest[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; | ||||
| @@ -225873,7 +225852,7 @@ public: | |||||
| if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, | if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, | ||||
| (WAVEFORMATEX*) &format, 0))) | (WAVEFORMATEX*) &format, 0))) | ||||
| if (! rates.contains (ratesToTest[i])) | if (! rates.contains (ratesToTest[i])) | ||||
| rates.addSorted (comparator, ratesToTest[i]); | |||||
| rates.addUsingDefaultSort (ratesToTest[i]); | |||||
| } | } | ||||
| } | } | ||||
| @@ -226024,6 +226003,9 @@ private: | |||||
| return false; | return false; | ||||
| } | } | ||||
| WASAPIDeviceBase (const WASAPIDeviceBase&); | |||||
| WASAPIDeviceBase& operator= (const WASAPIDeviceBase&); | |||||
| }; | }; | ||||
| class WASAPIInputDevice : public WASAPIDeviceBase | class WASAPIInputDevice : public WASAPIDeviceBase | ||||
| @@ -226169,6 +226151,10 @@ public: | |||||
| ComSmartPtr <IAudioCaptureClient> captureClient; | ComSmartPtr <IAudioCaptureClient> captureClient; | ||||
| MemoryBlock reservoir; | MemoryBlock reservoir; | ||||
| int reservoirSize, reservoirCapacity; | int reservoirSize, reservoirCapacity; | ||||
| private: | |||||
| WASAPIInputDevice (const WASAPIInputDevice&); | |||||
| WASAPIInputDevice& operator= (const WASAPIInputDevice&); | |||||
| }; | }; | ||||
| class WASAPIOutputDevice : public WASAPIDeviceBase | class WASAPIOutputDevice : public WASAPIDeviceBase | ||||
| @@ -226260,6 +226246,10 @@ public: | |||||
| } | } | ||||
| ComSmartPtr <IAudioRenderClient> renderClient; | ComSmartPtr <IAudioRenderClient> renderClient; | ||||
| private: | |||||
| WASAPIOutputDevice (const WASAPIOutputDevice&); | |||||
| WASAPIOutputDevice& operator= (const WASAPIOutputDevice&); | |||||
| }; | }; | ||||
| class WASAPIAudioIODevice : public AudioIODevice, | class WASAPIAudioIODevice : public AudioIODevice, | ||||
| @@ -226321,16 +226311,15 @@ public: | |||||
| sampleRates = d->rates; | sampleRates = d->rates; | ||||
| } | } | ||||
| IntegerElementComparator<int> comparator; | |||||
| bufferSizes.addSorted (comparator, defaultBufferSize); | |||||
| bufferSizes.addUsingDefaultSort (defaultBufferSize); | |||||
| if (minBufferSize != defaultBufferSize) | if (minBufferSize != defaultBufferSize) | ||||
| bufferSizes.addSorted (comparator, minBufferSize); | |||||
| bufferSizes.addUsingDefaultSort (minBufferSize); | |||||
| int n = 64; | int n = 64; | ||||
| for (int i = 0; i < 40; ++i) | for (int i = 0; i < 40; ++i) | ||||
| { | { | ||||
| if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) | if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) | ||||
| bufferSizes.addSorted (comparator, n); | |||||
| bufferSizes.addUsingDefaultSort (n); | |||||
| n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); | n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); | ||||
| } | } | ||||
| @@ -1860,24 +1860,15 @@ static int findInsertIndexInSortedArray (ElementComparator& comparator, | |||||
| } | } | ||||
| template <class ElementType> | template <class ElementType> | ||||
| class IntegerElementComparator | |||||
| class DefaultElementComparator | |||||
| { | { | ||||
| public: | |||||
| static int compareElements (const ElementType first, | |||||
| const ElementType second) throw() | |||||
| { | |||||
| return (first < second) ? -1 : ((first == second) ? 0 : 1); | |||||
| } | |||||
| }; | |||||
| private: | |||||
| typedef PARAMETER_TYPE (ElementType) ParameterType; | |||||
| template <class ElementType> | |||||
| class FloatElementComparator | |||||
| { | |||||
| public: | public: | ||||
| static int compareElements (const ElementType first, | |||||
| const ElementType second) throw() | |||||
| static int compareElements (ParameterType first, ParameterType second) | |||||
| { | { | ||||
| return (first < second) ? -1 : ((first == second) ? 0 : 1); | |||||
| return (first < second) ? -1 : ((first < second) ? 1 : 0); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -2297,6 +2288,12 @@ public: | |||||
| insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed), newElement); | insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed), newElement); | ||||
| } | } | ||||
| void addUsingDefaultSort (ParameterType newElement) | |||||
| { | |||||
| DefaultElementComparator <ElementType> comparator; | |||||
| addSorted (comparator, newElement); | |||||
| } | |||||
| template <class ElementComparator> | template <class ElementComparator> | ||||
| int indexOfSorted (ElementComparator& comparator, ParameterType elementToLookFor) const | int indexOfSorted (ElementComparator& comparator, ParameterType elementToLookFor) const | ||||
| { | { | ||||
| @@ -5890,9 +5887,8 @@ public: | |||||
| { | { | ||||
| removeRange (firstValue, numValuesToAdd); | removeRange (firstValue, numValuesToAdd); | ||||
| IntegerElementComparator<Type> sorter; | |||||
| values.addSorted (sorter, firstValue); | |||||
| values.addSorted (sorter, firstValue + numValuesToAdd); | |||||
| values.addUsingDefaultSort (firstValue); | |||||
| values.addUsingDefaultSort (firstValue + numValuesToAdd); | |||||
| simplify(); | simplify(); | ||||
| } | } | ||||
| @@ -5926,13 +5922,11 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| IntegerElementComparator<Type> sorter; | |||||
| if (onAtStart) | if (onAtStart) | ||||
| values.addSorted (sorter, firstValue); | |||||
| values.addUsingDefaultSort (firstValue); | |||||
| if (onAtEnd) | if (onAtEnd) | ||||
| values.addSorted (sorter, lastValue); | |||||
| values.addUsingDefaultSort (lastValue); | |||||
| simplify(); | simplify(); | ||||
| } | } | ||||
| @@ -26231,16 +26225,17 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| class ActiveXControlData; | |||||
| friend class ActiveXControlData; | |||||
| void* control; | |||||
| class Pimpl; | |||||
| friend class Pimpl; | |||||
| friend class ScopedPointer <Pimpl>; | |||||
| ScopedPointer <Pimpl> control; | |||||
| bool mouseEventsAllowed; | bool mouseEventsAllowed; | ||||
| ActiveXControlComponent (const ActiveXControlComponent&); | |||||
| ActiveXControlComponent& operator= (const ActiveXControlComponent&); | |||||
| void setControlBounds (const Rectangle<int>& bounds) const; | void setControlBounds (const Rectangle<int>& bounds) const; | ||||
| void setControlVisible (bool b) const; | void setControlVisible (bool b) const; | ||||
| ActiveXControlComponent (const ActiveXControlComponent&); | |||||
| ActiveXControlComponent& operator= (const ActiveXControlComponent&); | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| @@ -329,7 +329,7 @@ public: | |||||
| /** Appends a new element at the end of the array. | /** Appends a new element at the end of the array. | ||||
| @param newElement the new object to add to the array | @param newElement the new object to add to the array | ||||
| @see set, insert, addIfNotAlreadyThere, addSorted, addArray | |||||
| @see set, insert, addIfNotAlreadyThere, addSorted, addUsingDefaultSort, addArray | |||||
| */ | */ | ||||
| void add (ParameterType newElement) | void add (ParameterType newElement) | ||||
| { | { | ||||
| @@ -348,7 +348,7 @@ public: | |||||
| @param indexToInsertAt the index at which the new element should be | @param indexToInsertAt the index at which the new element should be | ||||
| inserted (pass in -1 to add it to the end) | inserted (pass in -1 to add it to the end) | ||||
| @param newElement the new object to add to the array | @param newElement the new object to add to the array | ||||
| @see add, addSorted, set | |||||
| @see add, addSorted, addUsingDefaultSort, set | |||||
| */ | */ | ||||
| void insert (int indexToInsertAt, ParameterType newElement) | void insert (int indexToInsertAt, ParameterType newElement) | ||||
| { | { | ||||
| @@ -580,7 +580,7 @@ public: | |||||
| @param comparator the comparator to use to compare the elements - see the sort() | @param comparator the comparator to use to compare the elements - see the sort() | ||||
| method for details about the form this object should take | method for details about the form this object should take | ||||
| @param newElement the new element to insert to the array | @param newElement the new element to insert to the array | ||||
| @see add, sort | |||||
| @see addUsingDefaultSort, add, sort | |||||
| */ | */ | ||||
| template <class ElementComparator> | template <class ElementComparator> | ||||
| void addSorted (ElementComparator& comparator, ParameterType newElement) | void addSorted (ElementComparator& comparator, ParameterType newElement) | ||||
| @@ -589,6 +589,21 @@ public: | |||||
| insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed), newElement); | insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed), newElement); | ||||
| } | } | ||||
| /** Inserts a new element into the array, assuming that the array is sorted. | |||||
| This will use the DefaultElementComparator class for sorting, so your ElementType | |||||
| must be suitable for use with that class. If the array isn't sorted, the behaviour of this | |||||
| method will be unpredictable. | |||||
| @param newElement the new element to insert to the array | |||||
| @see addSorted, sort | |||||
| */ | |||||
| void addUsingDefaultSort (ParameterType newElement) | |||||
| { | |||||
| DefaultElementComparator <ElementType> comparator; | |||||
| addSorted (comparator, newElement); | |||||
| } | |||||
| /** Finds the index of an element in the array, assuming that the array is sorted. | /** Finds the index of an element in the array, assuming that the array is sorted. | ||||
| This will use a comparator to do a binary-chop to find the index of the given | This will use a comparator to do a binary-chop to find the index of the given | ||||
| @@ -258,58 +258,30 @@ static int findInsertIndexInSortedArray (ElementComparator& comparator, | |||||
| //============================================================================== | //============================================================================== | ||||
| /** | /** | ||||
| A simple ElementComparator class that can be used to sort an array of | A simple ElementComparator class that can be used to sort an array of | ||||
| integer primitive objects. | |||||
| objects that support the '<' operator. | |||||
| This will work for primitive types and objects that implement operator<(). | |||||
| Example: @code | Example: @code | ||||
| Array <int> myArray; | Array <int> myArray; | ||||
| IntegerElementComparator<int> sorter; | |||||
| DefaultElementComparator<int> sorter; | |||||
| myArray.sort (sorter); | myArray.sort (sorter); | ||||
| @endcode | @endcode | ||||
| For floating point values, see the FloatElementComparator class instead. | |||||
| @see FloatElementComparator, ElementComparator | |||||
| @see ElementComparator | |||||
| */ | */ | ||||
| template <class ElementType> | template <class ElementType> | ||||
| class IntegerElementComparator | |||||
| class DefaultElementComparator | |||||
| { | { | ||||
| public: | |||||
| static int compareElements (const ElementType first, | |||||
| const ElementType second) throw() | |||||
| { | |||||
| return (first < second) ? -1 : ((first == second) ? 0 : 1); | |||||
| } | |||||
| }; | |||||
| //============================================================================== | |||||
| /** | |||||
| A simple ElementComparator class that can be used to sort an array of numeric | |||||
| double or floating point primitive objects. | |||||
| private: | |||||
| typedef PARAMETER_TYPE (ElementType) ParameterType; | |||||
| Example: @code | |||||
| Array <double> myArray; | |||||
| FloatElementComparator<double> sorter; | |||||
| myArray.sort (sorter); | |||||
| @endcode | |||||
| For integer values, see the IntegerElementComparator class instead. | |||||
| @see IntegerElementComparator, ElementComparator | |||||
| */ | |||||
| template <class ElementType> | |||||
| class FloatElementComparator | |||||
| { | |||||
| public: | public: | ||||
| static int compareElements (const ElementType first, | |||||
| const ElementType second) throw() | |||||
| static int compareElements (ParameterType first, ParameterType second) | |||||
| { | { | ||||
| return (first < second) ? -1 : ((first == second) ? 0 : 1); | |||||
| return (first < second) ? -1 : ((first < second) ? 1 : 0); | |||||
| } | } | ||||
| }; | }; | ||||
| #endif // __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__ | #endif // __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__ | ||||
| @@ -199,9 +199,8 @@ public: | |||||
| { | { | ||||
| removeRange (firstValue, numValuesToAdd); | removeRange (firstValue, numValuesToAdd); | ||||
| IntegerElementComparator<Type> sorter; | |||||
| values.addSorted (sorter, firstValue); | |||||
| values.addSorted (sorter, firstValue + numValuesToAdd); | |||||
| values.addUsingDefaultSort (firstValue); | |||||
| values.addUsingDefaultSort (firstValue + numValuesToAdd); | |||||
| simplify(); | simplify(); | ||||
| } | } | ||||
| @@ -242,13 +241,11 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| IntegerElementComparator<Type> sorter; | |||||
| if (onAtStart) | if (onAtStart) | ||||
| values.addSorted (sorter, firstValue); | |||||
| values.addUsingDefaultSort (firstValue); | |||||
| if (onAtEnd) | if (onAtEnd) | ||||
| values.addSorted (sorter, lastValue); | |||||
| values.addUsingDefaultSort (lastValue); | |||||
| simplify(); | simplify(); | ||||
| } | } | ||||
| @@ -264,6 +264,7 @@ public: | |||||
| @param newIndex the index at which you'd like this item to end up. If this | @param newIndex the index at which you'd like this item to end up. If this | ||||
| is less than zero, the value will be moved to the end | is less than zero, the value will be moved to the end | ||||
| of the list | of the list | ||||
| @param undoManager the optional UndoManager to use to store this transaction | |||||
| */ | */ | ||||
| void moveChild (int currentIndex, int newIndex, UndoManager* undoManager); | void moveChild (int currentIndex, int newIndex, UndoManager* undoManager); | ||||
| @@ -116,16 +116,17 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| class ActiveXControlData; | |||||
| friend class ActiveXControlData; | |||||
| void* control; | |||||
| class Pimpl; | |||||
| friend class Pimpl; | |||||
| friend class ScopedPointer <Pimpl>; | |||||
| ScopedPointer <Pimpl> control; | |||||
| bool mouseEventsAllowed; | bool mouseEventsAllowed; | ||||
| ActiveXControlComponent (const ActiveXControlComponent&); | |||||
| ActiveXControlComponent& operator= (const ActiveXControlComponent&); | |||||
| void setControlBounds (const Rectangle<int>& bounds) const; | void setControlBounds (const Rectangle<int>& bounds) const; | ||||
| void setControlVisible (bool b) const; | void setControlVisible (bool b) const; | ||||
| ActiveXControlComponent (const ActiveXControlComponent&); | |||||
| ActiveXControlComponent& operator= (const ActiveXControlComponent&); | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| @@ -171,7 +171,6 @@ namespace ActiveXHelpers | |||||
| HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo) | HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo) | ||||
| { | { | ||||
| // frame->AddRef(); // MS docs are unclear about whether this is needed, but it seems to lead to a memory leak.. | |||||
| *lplpFrame = frame; | *lplpFrame = frame; | ||||
| *lplpDoc = 0; | *lplpDoc = 0; | ||||
| lpFrameInfo->fMDIApp = FALSE; | lpFrameInfo->fMDIApp = FALSE; | ||||
| @@ -292,7 +291,7 @@ namespace ActiveXHelpers | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| class ActiveXControlComponent::ActiveXControlData : public ComponentMovementWatcher | |||||
| class ActiveXControlComponent::Pimpl : public ComponentMovementWatcher | |||||
| { | { | ||||
| ActiveXControlComponent* const owner; | ActiveXControlComponent* const owner; | ||||
| bool wasShowing; | bool wasShowing; | ||||
| @@ -304,8 +303,7 @@ public: | |||||
| IOleObject* control; | IOleObject* control; | ||||
| //============================================================================== | //============================================================================== | ||||
| ActiveXControlData (HWND hwnd, | |||||
| ActiveXControlComponent* const owner_) | |||||
| Pimpl (HWND hwnd, ActiveXControlComponent* const owner_) | |||||
| : ComponentMovementWatcher (owner_), | : ComponentMovementWatcher (owner_), | ||||
| owner (owner_), | owner (owner_), | ||||
| wasShowing (owner_ != 0 && owner_->isShowing()), | wasShowing (owner_ != 0 && owner_->isShowing()), | ||||
| @@ -316,7 +314,7 @@ public: | |||||
| { | { | ||||
| } | } | ||||
| ~ActiveXControlData() | |||||
| ~Pimpl() | |||||
| { | { | ||||
| if (control != 0) | if (control != 0) | ||||
| { | { | ||||
| @@ -359,20 +357,15 @@ public: | |||||
| componentPeerChanged(); | componentPeerChanged(); | ||||
| } | } | ||||
| static bool doesWindowMatch (const ActiveXControlComponent* const ax, HWND hwnd) | |||||
| { | |||||
| return ((ActiveXControlData*) ax->control) != 0 | |||||
| && ((ActiveXControlData*) ax->control)->controlHWND == hwnd; | |||||
| } | |||||
| // intercepts events going to an activeX control, so we can sneakily use the mouse events | // intercepts events going to an activeX control, so we can sneakily use the mouse events | ||||
| static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | ||||
| { | { | ||||
| for (int i = ActiveXHelpers::activeXComps.size(); --i >= 0;) | for (int i = ActiveXHelpers::activeXComps.size(); --i >= 0;) | ||||
| { | { | ||||
| const ActiveXControlComponent* const ax = (const ActiveXControlComponent*) ActiveXHelpers::activeXComps.getUnchecked(i); | |||||
| const ActiveXControlComponent* const ax | |||||
| = static_cast <const ActiveXControlComponent*> (ActiveXHelpers::activeXComps.getUnchecked(i)); | |||||
| if (doesWindowMatch (ax, hwnd)) | |||||
| if (ax->control != 0 && ax->control->controlHWND == hwnd) | |||||
| { | { | ||||
| switch (message) | switch (message) | ||||
| { | { | ||||
| @@ -404,7 +397,7 @@ public: | |||||
| break; | break; | ||||
| } | } | ||||
| return CallWindowProc ((WNDPROC) (ax->originalWndProc), hwnd, message, wParam, lParam); | |||||
| return CallWindowProc ((WNDPROC) ax->originalWndProc, hwnd, message, wParam, lParam); | |||||
| } | } | ||||
| } | } | ||||
| @@ -414,7 +407,6 @@ public: | |||||
| ActiveXControlComponent::ActiveXControlComponent() | ActiveXControlComponent::ActiveXControlComponent() | ||||
| : originalWndProc (0), | : originalWndProc (0), | ||||
| control (0), | |||||
| mouseEventsAllowed (true) | mouseEventsAllowed (true) | ||||
| { | { | ||||
| ActiveXHelpers::activeXComps.add (this); | ActiveXHelpers::activeXComps.add (this); | ||||
| @@ -445,16 +437,16 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||||
| const Point<int> pos (relativePositionToOtherComponent (getTopLevelComponent(), Point<int>())); | const Point<int> pos (relativePositionToOtherComponent (getTopLevelComponent(), Point<int>())); | ||||
| HWND hwnd = (HWND) peer->getNativeHandle(); | HWND hwnd = (HWND) peer->getNativeHandle(); | ||||
| ScopedPointer <ActiveXControlData> info (new ActiveXControlData (hwnd, this)); | |||||
| ScopedPointer<Pimpl> newControl (new Pimpl (hwnd, this)); | |||||
| HRESULT hr; | HRESULT hr; | ||||
| if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0, | if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0, | ||||
| info->clientSite, info->storage, | |||||
| (void**) &(info->control))) == S_OK) | |||||
| newControl->clientSite, newControl->storage, | |||||
| (void**) &(newControl->control))) == S_OK) | |||||
| { | { | ||||
| info->control->SetHostNames (L"Juce", 0); | |||||
| newControl->control->SetHostNames (L"Juce", 0); | |||||
| if (OleSetContainedObject (info->control, TRUE) == S_OK) | |||||
| if (OleSetContainedObject (newControl->control, TRUE) == S_OK) | |||||
| { | { | ||||
| RECT rect; | RECT rect; | ||||
| rect.left = pos.getX(); | rect.left = pos.getX(); | ||||
| @@ -462,17 +454,17 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||||
| rect.right = pos.getX() + getWidth(); | rect.right = pos.getX() + getWidth(); | ||||
| rect.bottom = pos.getY() + getHeight(); | rect.bottom = pos.getY() + getHeight(); | ||||
| if (info->control->DoVerb (OLEIVERB_SHOW, 0, info->clientSite, 0, hwnd, &rect) == S_OK) | |||||
| if (newControl->control->DoVerb (OLEIVERB_SHOW, 0, newControl->clientSite, 0, hwnd, &rect) == S_OK) | |||||
| { | { | ||||
| control = info.release(); | |||||
| control = newControl; | |||||
| setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); | setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); | ||||
| ((ActiveXControlData*) control)->controlHWND = ActiveXHelpers::getHWND (this); | |||||
| control->controlHWND = ActiveXHelpers::getHWND (this); | |||||
| if (((ActiveXControlData*) control)->controlHWND != 0) | |||||
| if (control->controlHWND != 0) | |||||
| { | { | ||||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC); | |||||
| SetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC, (LONG_PTR) ActiveXControlData::activeXHookWndProc); | |||||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC); | |||||
| SetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC, (LONG_PTR) Pimpl::activeXHookWndProc); | |||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -486,24 +478,16 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||||
| void ActiveXControlComponent::deleteControl() | void ActiveXControlComponent::deleteControl() | ||||
| { | { | ||||
| ActiveXControlData* const info = (ActiveXControlData*) control; | |||||
| if (info != 0) | |||||
| { | |||||
| delete info; | |||||
| control = 0; | |||||
| originalWndProc = 0; | |||||
| } | |||||
| control = 0; | |||||
| originalWndProc = 0; | |||||
| } | } | ||||
| void* ActiveXControlComponent::queryInterface (const void* iid) const | void* ActiveXControlComponent::queryInterface (const void* iid) const | ||||
| { | { | ||||
| ActiveXControlData* const info = (ActiveXControlData*) control; | |||||
| void* result = 0; | void* result = 0; | ||||
| if (info != 0 && info->control != 0 | |||||
| && info->control->QueryInterface (*(const IID*) iid, &result) == S_OK) | |||||
| if (control != 0 && control->control != 0 | |||||
| && SUCCEEDED (control->control->QueryInterface (*(const IID*) iid, &result))) | |||||
| return result; | return result; | ||||
| return 0; | return 0; | ||||
| @@ -511,18 +495,14 @@ void* ActiveXControlComponent::queryInterface (const void* iid) const | |||||
| void ActiveXControlComponent::setControlBounds (const Rectangle<int>& newBounds) const | void ActiveXControlComponent::setControlBounds (const Rectangle<int>& newBounds) const | ||||
| { | { | ||||
| HWND hwnd = ((ActiveXControlData*) control)->controlHWND; | |||||
| if (hwnd != 0) | |||||
| MoveWindow (hwnd, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); | |||||
| if (control->controlHWND != 0) | |||||
| MoveWindow (control->controlHWND, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); | |||||
| } | } | ||||
| void ActiveXControlComponent::setControlVisible (const bool shouldBeVisible) const | void ActiveXControlComponent::setControlVisible (const bool shouldBeVisible) const | ||||
| { | { | ||||
| HWND hwnd = ((ActiveXControlData*) control)->controlHWND; | |||||
| if (hwnd != 0) | |||||
| ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE); | |||||
| if (control->controlHWND != 0) | |||||
| ShowWindow (control->controlHWND, shouldBeVisible ? SW_SHOWNA : SW_HIDE); | |||||
| } | } | ||||
| void ActiveXControlComponent::setMouseEventsAllowed (const bool eventsCanReachControl) | void ActiveXControlComponent::setMouseEventsAllowed (const bool eventsCanReachControl) | ||||
| @@ -155,8 +155,7 @@ public: | |||||
| minBufferSize = wasapi_refTimeToSamples (minPeriod, defaultSampleRate); | minBufferSize = wasapi_refTimeToSamples (minPeriod, defaultSampleRate); | ||||
| defaultBufferSize = wasapi_refTimeToSamples (defaultPeriod, defaultSampleRate); | defaultBufferSize = wasapi_refTimeToSamples (defaultPeriod, defaultSampleRate); | ||||
| FloatElementComparator<double> comparator; | |||||
| rates.addSorted (comparator, defaultSampleRate); | |||||
| rates.addUsingDefaultSort (defaultSampleRate); | |||||
| static const double ratesToTest[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; | static const double ratesToTest[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; | ||||
| @@ -170,7 +169,7 @@ public: | |||||
| if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, | if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, | ||||
| (WAVEFORMATEX*) &format, 0))) | (WAVEFORMATEX*) &format, 0))) | ||||
| if (! rates.contains (ratesToTest[i])) | if (! rates.contains (ratesToTest[i])) | ||||
| rates.addSorted (comparator, ratesToTest[i]); | |||||
| rates.addUsingDefaultSort (ratesToTest[i]); | |||||
| } | } | ||||
| } | } | ||||
| @@ -321,6 +320,9 @@ private: | |||||
| return false; | return false; | ||||
| } | } | ||||
| WASAPIDeviceBase (const WASAPIDeviceBase&); | |||||
| WASAPIDeviceBase& operator= (const WASAPIDeviceBase&); | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -467,6 +469,10 @@ public: | |||||
| ComSmartPtr <IAudioCaptureClient> captureClient; | ComSmartPtr <IAudioCaptureClient> captureClient; | ||||
| MemoryBlock reservoir; | MemoryBlock reservoir; | ||||
| int reservoirSize, reservoirCapacity; | int reservoirSize, reservoirCapacity; | ||||
| private: | |||||
| WASAPIInputDevice (const WASAPIInputDevice&); | |||||
| WASAPIInputDevice& operator= (const WASAPIInputDevice&); | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -559,6 +565,10 @@ public: | |||||
| } | } | ||||
| ComSmartPtr <IAudioRenderClient> renderClient; | ComSmartPtr <IAudioRenderClient> renderClient; | ||||
| private: | |||||
| WASAPIOutputDevice (const WASAPIOutputDevice&); | |||||
| WASAPIOutputDevice& operator= (const WASAPIOutputDevice&); | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -621,16 +631,15 @@ public: | |||||
| sampleRates = d->rates; | sampleRates = d->rates; | ||||
| } | } | ||||
| IntegerElementComparator<int> comparator; | |||||
| bufferSizes.addSorted (comparator, defaultBufferSize); | |||||
| bufferSizes.addUsingDefaultSort (defaultBufferSize); | |||||
| if (minBufferSize != defaultBufferSize) | if (minBufferSize != defaultBufferSize) | ||||
| bufferSizes.addSorted (comparator, minBufferSize); | |||||
| bufferSizes.addUsingDefaultSort (minBufferSize); | |||||
| int n = 64; | int n = 64; | ||||
| for (int i = 0; i < 40; ++i) | for (int i = 0; i < 40; ++i) | ||||
| { | { | ||||
| if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) | if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) | ||||
| bufferSizes.addSorted (comparator, n); | |||||
| bufferSizes.addUsingDefaultSort (n); | |||||
| n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); | n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); | ||||
| } | } | ||||