Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ This is a development build of the ARA Library 3.0.


Changes since previous releases:
- initial draft of ARA generator plug-ins that operate merely based on content descriptions (no sample input)
- initial draft of lyrics-related content types, tailored to support singing voice synthesis
- initial draft of region sequence persistency
- added isPlaybackRegionPreservingAudioSourceSignal(), superseding isAudioModificationPreservingAudioSourceSignal()
- initial draft of generic ARA IPC library providing a proxy host and a proxy plug-in,
based on heavily refactored IPC Example from earlier SDK releases
- dropped support for ARA 1 and 2.0 Draft APIs
If previously optionally supporting obsolete ARA 1 persistency, now exclusively use ARA 2 persistency.
- C++14 is now consistently required on all platforms
- C++17 is now consistently required on all platforms
- fixed inconsistent spelling of "timestretch" in various identifiers


=== ARA SDK 2.3 release (aka 2.3.001) (2025/11/07) ===
Expand Down
21 changes: 19 additions & 2 deletions Debug/ARAContentLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ struct ContentLogger

// array of all content types defined in the api

static inline constexpr std::array<ARAContentType, 6> getAllContentTypes () noexcept
static inline constexpr std::array<ARAContentType, 7> getAllContentTypes () noexcept
{
return { { kARAContentTypeNotes,
kARAContentTypeTempoEntries, kARAContentTypeBarSignatures,
kARAContentTypeStaticTuning,
kARAContentTypeKeySignatures, kARAContentTypeSheetChords
kARAContentTypeKeySignatures, kARAContentTypeSheetChords,
kARAContentTypeLyricEntries
} };
}

Expand Down Expand Up @@ -88,6 +89,7 @@ struct ContentLogger
case kARAContentTypeStaticTuning: return ContentTypeMapper<kARAContentTypeStaticTuning>::enumName;
case kARAContentTypeKeySignatures: return ContentTypeMapper<kARAContentTypeKeySignatures>::enumName;
case kARAContentTypeSheetChords: return ContentTypeMapper<kARAContentTypeSheetChords>::enumName;
case kARAContentTypeLyricEntries: return ContentTypeMapper<kARAContentTypeLyricEntries>::enumName;
default: ARA_INTERNAL_ASSERT (false); return "kARAContentType???";
}
}
Expand All @@ -102,6 +104,7 @@ struct ContentLogger
case kARAContentTypeStaticTuning: return ContentTypeMapper<kARAContentTypeStaticTuning>::typeName;
case kARAContentTypeKeySignatures: return ContentTypeMapper<kARAContentTypeKeySignatures>::typeName;
case kARAContentTypeSheetChords: return ContentTypeMapper<kARAContentTypeSheetChords>::typeName;
case kARAContentTypeLyricEntries: return ContentTypeMapper<kARAContentTypeLyricEntries>::typeName;
default: ARA_INTERNAL_ASSERT (false); return "ARAContent???";
}
}
Expand Down Expand Up @@ -188,6 +191,14 @@ struct ContentLogger
(logGivenName && logParsedName) ? " aka " : "", (logGivenName && logParsedName) ? parsedChordName.c_str () : "", chordData.position);
}

static inline void logEvent (ARAInt32 idx, const ARAContentLyricsEntry& lyricsEntry)
{
ARA_LOG ("%s[%i] %s%s, %i %s phonemes%s, position = %.3f", getTypeNameForContentType (kARAContentTypeLyricEntries), idx,
(lyricsEntry.continuesPreviousWord) ? "-" : "", lyricsEntry.lyrics,
lyricsEntry.phonemeCount, getNameForContentGrade (lyricsEntry.phonemesGrade),
(lyricsEntry.phonemeOffsets) ? " w/ offsets": "", lyricsEntry.position);
}

// internal helper for log ()

template <ARAContentType contentType, typename ContentReader, std::enable_if_t<contentType != kARAContentTypeTempoEntries, bool> = true>
Expand Down Expand Up @@ -247,6 +258,7 @@ struct ContentLogger
case kARAContentTypeStaticTuning: return log<kARAContentTypeStaticTuning> (controller, modelObjectRef, range, logIfNotAvailable);
case kARAContentTypeKeySignatures: return log<kARAContentTypeKeySignatures> (controller, modelObjectRef, range, logIfNotAvailable);
case kARAContentTypeSheetChords: return log<kARAContentTypeSheetChords> (controller, modelObjectRef, range, logIfNotAvailable);
case kARAContentTypeLyricEntries: return log<kARAContentTypeLyricEntries> (controller, modelObjectRef, range, logIfNotAvailable);
default: ARA_INTERNAL_ASSERT (false); return false;
}
}
Expand Down Expand Up @@ -316,6 +328,11 @@ struct ContentLogger
log<kARAContentTypeKeySignatures> (controller, modelObjectRef, range, false);
log<kARAContentTypeSheetChords> (controller, modelObjectRef, range, false);
}
if (scopeFlags.affectLyrics ())
{
ARA_LOG ("lyrics scope updated, related content is:");
log<kARAContentTypeLyricEntries> (controller, modelObjectRef, range, false);
}
}
};

Expand Down
19 changes: 19 additions & 0 deletions Debug/ARAContentValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,25 @@ struct ContentReaderValidatorImplementation<kARAContentTypeSheetChords>
}
};

template <>
struct ContentReaderValidatorImplementation<kARAContentTypeLyricEntries>
{
static inline void validateEventCount (ARAInt32 eventCount) { ARA_VALIDATE_API_CONDITION (eventCount >= 0); }

static inline void validateEvent (const ARAContentLyricsEntry* event)
{
ARA_VALIDATE_API_CONDITION ((event->continuesPreviousWord == kARAFalse) || (event->lyrics != nullptr));
ARA_VALIDATE_API_CONDITION ((event->phonemeCount == 0) || (event->phonemes != nullptr));
ARA_VALIDATE_API_CONDITION ((event->phonemeCount != 0) || (event->phonemes == nullptr));
ARA_VALIDATE_API_CONDITION ((event->phonemeCount != 0) || (event->phonemeOffsets == nullptr));
}

static inline void validateEventSequence (const ARAContentLyricsEntry* event, const ARAContentLyricsEntry* prevEvent)
{
ARA_VALIDATE_API_CONDITION (prevEvent->position < event->position);
}
};


/*******************************************************************************/
// ContentReaderValidator
Expand Down
1 change: 1 addition & 0 deletions Dispatch/ARAContentReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct ContentTypeMapper;
ARA_SPECIALIZE_CONTENT_TYPE_MAPPER (kARAContentTypeStaticTuning, ARAContentTuning)
ARA_SPECIALIZE_CONTENT_TYPE_MAPPER (kARAContentTypeKeySignatures, ARAContentKeySignature)
ARA_SPECIALIZE_CONTENT_TYPE_MAPPER (kARAContentTypeSheetChords, ARAContentChord)
ARA_SPECIALIZE_CONTENT_TYPE_MAPPER (kARAContentTypeLyricEntries, ARAContentLyricsEntry)

#undef ARA_SPECIALIZE_CONTENT_TYPE_MAPPER

Expand Down
10 changes: 7 additions & 3 deletions Dispatch/ARADispatchBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ class ContentUpdateScopes
static constexpr ContentUpdateScopes tuningIsAffected () noexcept { return nothingIsAffected ()._flags & ~kARAContentUpdateTuningScopeRemainsUnchanged; }
//! Content readers for key signatures, chords etc. are affected by the change.
static constexpr ContentUpdateScopes harmoniesAreAffected () noexcept { return nothingIsAffected ()._flags & ~kARAContentUpdateHarmonicScopeRemainsUnchanged; }
//! Content readers for lyrics, phonemes etc. are affected by the change.
static constexpr ContentUpdateScopes lyricsAreAffected () noexcept { return nothingIsAffected ()._flags & ~kARAContentUpdateLyricsScopeRemainsUnchanged; }

//! Everything is affected by the change.
static constexpr ContentUpdateScopes everythingIsAffected () noexcept { return kARAContentUpdateEverythingChanged; }
Expand Down Expand Up @@ -376,14 +378,16 @@ class ContentUpdateScopes
constexpr bool affectTuning () const noexcept { return ((_flags & kARAContentUpdateTuningScopeRemainsUnchanged) == 0); }
//! \copybrief harmoniesAreAffected
constexpr bool affectHarmonies () const noexcept { return ((_flags & kARAContentUpdateHarmonicScopeRemainsUnchanged) == 0); }
//! \copybrief lyricsAreAffected
constexpr bool affectLyrics () const noexcept { return ((_flags & kARAContentUpdateLyricsScopeRemainsUnchanged) == 0); }
//! \copybrief everythingIsAffected
constexpr bool affectEverything () const noexcept { return ((_flags & _knownFlags) == 0); }
//@}

private:
static constexpr ARAContentUpdateFlags _knownFlags { (kARAContentUpdateSignalScopeRemainsUnchanged |
kARAContentUpdateNoteScopeRemainsUnchanged | kARAContentUpdateTimingScopeRemainsUnchanged |
kARAContentUpdateTuningScopeRemainsUnchanged | kARAContentUpdateHarmonicScopeRemainsUnchanged) };
static constexpr ARAContentUpdateFlags _knownFlags { (kARAContentUpdateSignalScopeRemainsUnchanged | kARAContentUpdateNoteScopeRemainsUnchanged |
kARAContentUpdateTimingScopeRemainsUnchanged | kARAContentUpdateTuningScopeRemainsUnchanged |
kARAContentUpdateHarmonicScopeRemainsUnchanged | kARAContentUpdateLyricsScopeRemainsUnchanged) };
ARAContentUpdateFlags _flags;
};

Expand Down
22 changes: 20 additions & 2 deletions Dispatch/ARAHostDispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,21 @@ namespace ModelUpdateControllerDispatcher
fromHostRef (controllerHostRef)->notifyDocumentDataChanged ();
}

static void ARA_CALL notifyRegionSequenceDataChanged (ARAModelUpdateControllerHostRef controllerHostRef, ARARegionSequenceHostRef regionSequenceHostRef) noexcept
{
fromHostRef (controllerHostRef)->notifyRegionSequenceDataChanged (regionSequenceHostRef);
}

static const ARAModelUpdateControllerInterface* getInterface () noexcept
{
static const SizedStruct<&ARAModelUpdateControllerInterface::notifyDocumentDataChanged> ifc =
static const SizedStruct<&ARAModelUpdateControllerInterface::notifyRegionSequenceDataChanged> ifc =
{
ModelUpdateControllerDispatcher::notifyAudioSourceAnalysisProgress,
ModelUpdateControllerDispatcher::notifyAudioSourceContentChanged,
ModelUpdateControllerDispatcher::notifyAudioModificationContentChanged,
ModelUpdateControllerDispatcher::notifyPlaybackRegionContentChanged,
ModelUpdateControllerDispatcher::notifyDocumentDataChanged
ModelUpdateControllerDispatcher::notifyDocumentDataChanged,
ModelUpdateControllerDispatcher::notifyRegionSequenceDataChanged
};
return &ifc;
}
Expand Down Expand Up @@ -504,6 +510,18 @@ void DocumentController::updatePlaybackRegionProperties (ARAPlaybackRegionRef pl
getInterface ()->updatePlaybackRegionProperties (getRef (), playbackRegionRef, properties);
}

bool DocumentController::supportsIsPlaybackRegionPreservingAudioSourceSignal () noexcept
{
return getInterface ().implements<&ARADocumentControllerInterface::isPlaybackRegionPreservingAudioSourceSignal> ();
}

bool DocumentController::isPlaybackRegionPreservingAudioSourceSignal (ARAPlaybackRegionRef playbackRegionRef) noexcept
{
if (!supportsIsPlaybackRegionPreservingAudioSourceSignal ())
return false;
return (getInterface ()->isPlaybackRegionPreservingAudioSourceSignal (getRef (), playbackRegionRef) != kARAFalse);
}

void DocumentController::getPlaybackRegionHeadAndTailTime (ARAPlaybackRegionRef playbackRegionRef, ARATimeDuration* headTime, ARATimeDuration* tailTime) noexcept
{
return getInterface ()->getPlaybackRegionHeadAndTailTime (getRef (), playbackRegionRef, headTime, tailTime);
Expand Down
10 changes: 8 additions & 2 deletions Dispatch/ARAHostDispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ class ModelUpdateControllerInterface
virtual void notifyPlaybackRegionContentChanged (ARAPlaybackRegionHostRef playbackRegionHostRef, const ARAContentTimeRange* range, ContentUpdateScopes scopeFlags) noexcept = 0;
//! \copydoc ARAModelUpdateControllerInterface::notifyDocumentDataChanged
virtual void notifyDocumentDataChanged () noexcept = 0;
//! \copydoc ARAModelUpdateControllerInterface::notifyRegionSequenceDataChanged
ARA_DRAFT virtual void notifyRegionSequenceDataChanged (ARA::ARARegionSequenceHostRef regionSequenceHostRef) noexcept = 0;
};
ARA_MAP_HOST_REF (ModelUpdateControllerInterface, ARAModelUpdateControllerHostRef)

Expand Down Expand Up @@ -347,7 +349,7 @@ class DocumentController : public InterfaceInstance<ARADocumentControllerRef, AR
ARAAudioModificationRef cloneAudioModification (ARAAudioModificationRef audioModificationRef, ARAAudioModificationHostRef hostRef, const ARAAudioModificationProperties* properties) noexcept;
//! \copydoc ARADocumentControllerInterface::updateAudioModificationProperties
void updateAudioModificationProperties (ARAAudioModificationRef audioModificationRef, const ARAAudioModificationProperties* properties) noexcept;
//! Test whether isAudioModificationPreservingAudioSourceSignal () is supported by the plug-in.
//! Test whether isAudioModificationPreservingAudioSourceSignal() is supported by the plug-in.
bool supportsIsAudioModificationPreservingAudioSourceSignal () noexcept;
//! \copydoc ARADocumentControllerInterface::isAudioModificationPreservingAudioSourceSignal
bool isAudioModificationPreservingAudioSourceSignal (ARAAudioModificationRef audioModificationRef) noexcept;
Expand All @@ -358,12 +360,16 @@ class DocumentController : public InterfaceInstance<ARADocumentControllerRef, AR
//@}

//! @name Playback Region Management
//! (getPlaybackRegionHeadAndTailTime () resolves to no-op for pre-ARA-2.0 plug-ins and always returns 0.0 as times)
//! (getPlaybackRegionHeadAndTailTime() resolves to no-op for pre-ARA-2.0 plug-ins and always returns 0.0 as times)
//@{
//! \copydoc ARADocumentControllerInterface::createPlaybackRegion
ARAPlaybackRegionRef createPlaybackRegion (ARAAudioModificationRef audioModificationRef, ARAPlaybackRegionHostRef hostRef, const ARAPlaybackRegionProperties* properties) noexcept;
//! \copydoc ARADocumentControllerInterface::updatePlaybackRegionProperties
void updatePlaybackRegionProperties (ARAPlaybackRegionRef playbackRegionRef, const ARAPlaybackRegionProperties* properties) noexcept;
//! Test whether isPlaybackRegionPreservingAudioSourceSignal() is supported by the plug-in.
ARA_DRAFT bool supportsIsPlaybackRegionPreservingAudioSourceSignal () noexcept;
//! \copydoc ARADocumentControllerInterface::isPlaybackRegionPreservingAudioSourceSignal
ARA_DRAFT bool isPlaybackRegionPreservingAudioSourceSignal (ARAPlaybackRegionRef playbackRegionRef) noexcept;
//! \copydoc ARADocumentControllerInterface::getPlaybackRegionHeadAndTailTime
void getPlaybackRegionHeadAndTailTime (ARAPlaybackRegionRef playbackRegionRef, ARATimeDuration* headTime, ARATimeDuration* tailTime) noexcept;
//! \copydoc ARADocumentControllerInterface::destroyPlaybackRegion
Expand Down
41 changes: 33 additions & 8 deletions Dispatch/ARAPlugInDispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,9 @@ namespace DocumentControllerDispatcher
fromRef (controllerRef)->updatePlaybackRegionProperties (playbackRegionRef, properties);
}

static void ARA_CALL destroyPlaybackRegion (ARADocumentControllerRef controllerRef, ARAPlaybackRegionRef playbackRegionRef) noexcept
static ARABool ARA_CALL isPlaybackRegionPreservingAudioSourceSignal (ARADocumentControllerRef controllerRef, ARAPlaybackRegionRef playbackRegionRef) noexcept
{
fromRef (controllerRef)->destroyPlaybackRegion (playbackRegionRef);
return fromRef (controllerRef)->isPlaybackRegionPreservingAudioSourceSignal (playbackRegionRef) ? kARATrue : kARAFalse;
}

static void ARA_CALL getPlaybackRegionHeadAndTailTime (ARADocumentControllerRef controllerRef, ARAPlaybackRegionRef playbackRegionRef,
Expand All @@ -235,6 +235,11 @@ namespace DocumentControllerDispatcher
fromRef (controllerRef)->getPlaybackRegionHeadAndTailTime (playbackRegionRef, headTime, tailTime);
}

static void ARA_CALL destroyPlaybackRegion (ARADocumentControllerRef controllerRef, ARAPlaybackRegionRef playbackRegionRef) noexcept
{
fromRef (controllerRef)->destroyPlaybackRegion (playbackRegionRef);
}

// Content Reader Management

static ARABool ARA_CALL isAudioSourceContentAvailable (ARADocumentControllerRef controllerRef, ARAAudioSourceRef audioSourceRef, ARAContentType type) noexcept
Expand Down Expand Up @@ -342,7 +347,7 @@ namespace DocumentControllerDispatcher

static const ARADocumentControllerInterface* getInterface () noexcept
{
static const SizedStruct<&ARADocumentControllerInterface::isAudioModificationPreservingAudioSourceSignal> ifc =
static const SizedStruct<&ARADocumentControllerInterface::isPlaybackRegionPreservingAudioSourceSignal> ifc =
{
DocumentControllerDispatcher::destroyDocumentController,
DocumentControllerDispatcher::getFactory,
Expand Down Expand Up @@ -397,7 +402,8 @@ namespace DocumentControllerDispatcher
DocumentControllerDispatcher::requestProcessingAlgorithmForAudioSource,
DocumentControllerDispatcher::isLicensedForCapabilities,
DocumentControllerDispatcher::storeAudioSourceToAudioFileChunk,
DocumentControllerDispatcher::isAudioModificationPreservingAudioSourceSignal
DocumentControllerDispatcher::isAudioModificationPreservingAudioSourceSignal,
DocumentControllerDispatcher::isPlaybackRegionPreservingAudioSourceSignal
};
return &ifc;
}
Expand Down Expand Up @@ -645,21 +651,40 @@ void HostModelUpdateController::notifyAudioModificationContentChanged (ARAAudioM
getInterface ()->notifyAudioModificationContentChanged (getRef (), audioModificationHostRef, range, scopeFlags);
}

bool HostModelUpdateController::supportsNotifyPlaybackRegionContentChanged () noexcept
{
return getInterface ().implements<&ARAModelUpdateControllerInterface::notifyPlaybackRegionContentChanged> ();
}

void HostModelUpdateController::notifyPlaybackRegionContentChanged (ARAPlaybackRegionHostRef playbackRegionHostRef,
const ARAContentTimeRange* range, ContentUpdateScopes scopeFlags) noexcept
{
// notifyPlaybackRegionContentChanged was optional in the ARA 2.0 draft, so check its presence here to be safe
if (getInterface ().implements<&ARAModelUpdateControllerInterface::notifyPlaybackRegionContentChanged> ())
if (supportsNotifyPlaybackRegionContentChanged ())
getInterface ()->notifyPlaybackRegionContentChanged (getRef (), playbackRegionHostRef, range, scopeFlags);
}

bool HostModelUpdateController::supportsNotifyDocumentDataChanged () noexcept
{
return getInterface ().implements<&ARAModelUpdateControllerInterface::notifyDocumentDataChanged> ();
}

void HostModelUpdateController::notifyDocumentDataChanged () noexcept
{
// notifyDocumentDataChanged was added in ARA 2.3 draft, so check its presence here
if (getInterface ().implements<&ARAModelUpdateControllerInterface::notifyDocumentDataChanged> ())
if (supportsNotifyDocumentDataChanged ())
getInterface ()->notifyDocumentDataChanged (getRef ());
}

bool HostModelUpdateController::supportsNotifyRegionSequenceDataChanged () noexcept
{
return getInterface ().implements<&ARAModelUpdateControllerInterface::notifyRegionSequenceDataChanged> ();
}

void HostModelUpdateController::notifyRegionSequenceDataChanged (ARARegionSequenceHostRef regionSequenceHostRef) noexcept
{
if (supportsNotifyRegionSequenceDataChanged ())
getInterface ()->notifyRegionSequenceDataChanged (getRef (), regionSequenceHostRef);
}

/*******************************************************************************/
// PlaybackController
/*******************************************************************************/
Expand Down
Loading