mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 00:34:59 +01:00
Update libaaf to v1.0-1-gdef35bf
This commit is contained in:
parent
2b1349ffc2
commit
bd937366fd
38 changed files with 9153 additions and 7831 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2017-2023 Adrien Gesta-Fline
|
||||
* Copyright (C) 2017-2024 Adrien Gesta-Fline
|
||||
*
|
||||
* This file is part of libAAF.
|
||||
*
|
||||
|
|
@ -23,81 +23,70 @@
|
|||
#include "aaf/AAFIface.h"
|
||||
#include "aaf/ProTools.h"
|
||||
|
||||
#define PROTOOLS_CLIP_NAME_FADE_EN_LEN 5 // +1
|
||||
#define PROTOOLS_CLIP_NAME_FADE_DE_LEN 5 // +1
|
||||
#define PROTOOLS_CLIP_NAME_FADE_JA_LEN 5 // +1
|
||||
#define PROTOOLS_CLIP_NAME_FADE_FR_LEN 6 // +1
|
||||
#define PROTOOLS_CLIP_NAME_FADE_ES_LEN 8 // +1
|
||||
#define PROTOOLS_CLIP_NAME_FADE_ZH_CN_LEN 3 // +1
|
||||
#define PROTOOLS_CLIP_NAME_FADE_ZH_TW_LEN 3 // +1
|
||||
#define PROTOOLS_CLIP_NAME_FADE_KO_LEN 3 // +1
|
||||
|
||||
#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN_LEN 20 // +1
|
||||
#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE_LEN 24 // +1
|
||||
#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES_LEN 32 // +1
|
||||
#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR_LEN 33 // +1
|
||||
#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA_LEN 8 // +1
|
||||
#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN_LEN 6 // +1
|
||||
#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW_LEN 6 // +1
|
||||
#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO_LEN 11 // +1
|
||||
|
||||
/* English : "Fade " (Same as JA and DE) */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_FADE_EN[] = L"\x0046\x0061\x0064\x0065\x0020\x0000";
|
||||
/* German : "Fade " (Same as JA and EN) */
|
||||
// static const wchar_t PROTOOLS_CLIP_NAME_FADE_DE[] = L"\x0046\x0061\x0064\x0065\x0020\x0000";
|
||||
/* Japanese : "Fade " (Same as EN and DE) */
|
||||
// static const wchar_t PROTOOLS_CLIP_NAME_FADE_JA[] = L"\x0046\x0061\x0064\x0065\x0020\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_FADE_EN[] = "\x46\x61\x64\x65\x20";
|
||||
/* French : "Fondu " */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_FADE_FR[] = L"\x0046\x006f\x006e\x0064\x0075\x0020\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_FADE_FR[] = "\x46\x6f\x6e\x64\x75\x20";
|
||||
/* Spanish : "Fundido" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_FADE_ES[] = L"\x0046\x0075\x006e\x0064\x0069\x0064\x006f\x0020\x0000";
|
||||
/* Chinese (S) : "淡变 " */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_FADE_ZH_CN[] = L"\x6de1\x53d8\x0020\x0000";
|
||||
/* Chinese (T) : "淡變 " */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_FADE_ZH_TW[] = L"\x6de1\x8b8a\x0020\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_FADE_ES[] = "\x46\x75\x6e\x64\x69\x64\x6f\x20";
|
||||
/* Korean : "페이드" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_FADE_KO[] = L"\xd398\xc774\xb4dc\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_FADE_KO[] = "\xed\x8e\x98\xec\x9d\xb4\xeb\x93\x9c";
|
||||
/* Chinese (S) : "淡变 " */
|
||||
static const char PROTOOLS_CLIP_NAME_FADE_ZH_CN[] = "\xe6\xb7\xa1\xe5\x8f\x98\x20";
|
||||
/* Chinese (T) : "淡變 " */
|
||||
static const char PROTOOLS_CLIP_NAME_FADE_ZH_TW[] = "\xe6\xb7\xa1\xe8\xae\x8a\x20";
|
||||
|
||||
/* English : "Sample accurate edit" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN[] = L"\x0053\x0061\x006d\x0070\x006c\x0065\x0020\x0061\x0063\x0063\x0075\x0072\x0061\x0074\x0065\x0020\x0065\x0064\x0069\x0074\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN[] = "\x53\x61\x6d\x70\x6c\x65\x20\x61\x63\x63\x75\x72\x61\x74\x65\x20\x65\x64\x69\x74";
|
||||
/* German : "Samplegenaue Bearbeitung" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE[] = L"\x0053\x0061\x006d\x0070\x006c\x0065\x0067\x0065\x006e\x0061\x0075\x0065\x0020\x0042\x0065\x0061\x0072\x0062\x0065\x0069\x0074\x0075\x006e\x0067\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE[] = "\x53\x61\x6d\x70\x6c\x65\x67\x65\x6e\x61\x75\x65\x20\x42\x65\x61\x72\x62\x65\x69\x74\x75\x6e\x67";
|
||||
/* Spanish : "Edición con precisión de muestra" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES[] = L"\x0045\x0064\x0069\x0063\x0069\x00f3\x006e\x0020\x0063\x006f\x006e\x0020\x0070\x0072\x0065\x0063\x0069\x0073\x0069\x00f3\x006e\x0020\x0064\x0065\x0020\x006d\x0075\x0065\x0073\x0074\x0072\x0061\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES[] = "\x45\x64\x69\x63\x69\xc3\xb3\x6e\x20\x63\x6f\x6e\x20\x70\x72\x65\x63\x69\x73\x69\xc3\xb3\x6e\x20\x64\x65\x20\x6d\x75\x65\x73\x74\x72\x61";
|
||||
/* French : "Modification à l'échantillon près" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR[] = L"\x004d\x006f\x0064\x0069\x0066\x0069\x0063\x0061\x0074\x0069\x006f\x006e\x0020\x00e0\x0020\x006c\x0027\x00e9\x0063\x0068\x0061\x006e\x0074\x0069\x006c\x006c\x006f\x006e\x0020\x0070\x0072\x00e8\x0073\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR[] = "\x4d\x6f\x64\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x20\xc3\xa0\x20\x6c\x27\xc3\xa9\x63\x68\x61\x6e\x74\x69\x6c\x6c\x6f\x6e\x20\x70\x72\xc3\xa8\x73";
|
||||
/* Japanese : "サンプル精度編集" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA[] = L"\x30b5\x30f3\x30d7\x30eb\x7cbe\x5ea6\x7de8\x96c6\x0000";
|
||||
/* Chinese (S) : "精确采样编辑" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN[] = L"\x7cbe\x786e\x91c7\x6837\x7f16\x8f91\x0000";
|
||||
/* Chinese (T) : "精確取樣編輯" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW[] = L"\x7cbe\x78ba\x53d6\x6a23\x7de8\x8f2f\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA[] = "\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab\xe7\xb2\xbe\xe5\xba\xa6\xe7\xb7\xa8\xe9\x9b\x86";
|
||||
/* Korean : "샘플 단위 정밀 편집" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO[] = L"\xc0d8\xd50c\x0020\xb2e8\xc704\x0020\xc815\xbc00\x0020\xd3b8\xc9d1\x0000";
|
||||
static const char PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO[] = "\xec\x83\x98\xed\x94\x8c\x20\xeb\x8b\xa8\xec\x9c\x84\x20\xec\xa0\x95\xeb\xb0\x80\x20\xed\x8e\xb8\xec\xa7\x91";
|
||||
/* Chinese (S) : "精确采样编辑" */
|
||||
static const char PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN[] = "\xe7\xb2\xbe\xe7\xa1\xae\xe9\x87\x87\xe6\xa0\xb7\xe7\xbc\x96\xe8\xbe\x91";
|
||||
/* Chinese (T) : "精確取樣編輯" */
|
||||
static const char PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW[] = "\xe7\xb2\xbe\xe7\xa2\xba\xe5\x8f\x96\xe6\xa8\xa3\xe7\xb7\xa8\xe8\xbc\xaf";
|
||||
|
||||
#define debug(...) \
|
||||
AAF_LOG (aafi->log, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_DEBUG, __VA_ARGS__)
|
||||
|
||||
#define warning(...) \
|
||||
AAF_LOG (aafi->log, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_WARNING, __VA_ARGS__)
|
||||
|
||||
#define error(...) \
|
||||
AAF_LOG (aafi->log, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_ERROR, __VA_ARGS__)
|
||||
|
||||
static int
|
||||
is_rendered_fade (const wchar_t* clipName);
|
||||
is_rendered_fade (const char* clipName);
|
||||
static int
|
||||
is_sample_accurate_edit (const wchar_t* clipName);
|
||||
is_sample_accurate_edit (const char* clipName);
|
||||
static int
|
||||
replace_clipfade_with_fade (AAF_Iface* aafi, aafiTimelineItem* Item);
|
||||
remove_sampleAccurateEditClip (AAF_Iface* aafi, aafiAudioTrack* audioTrack, aafiTimelineItem* saeItem);
|
||||
static int
|
||||
replace_clipFade (AAF_Iface* aafi, aafiAudioTrack* audioTrack, aafiTimelineItem* fadeItem);
|
||||
|
||||
int
|
||||
protools_AAF (struct AAF_Iface* aafi)
|
||||
{
|
||||
int probe = 0;
|
||||
|
||||
/* TODO: CompanyName is "Digidesign, Inc." in ProTools 10.3.10.613 AAF, but what about since ? */
|
||||
/* NOTE: CompanyName is "Digidesign, Inc." at least since ProTools 10.3.10.613, and still today */
|
||||
|
||||
// if ( aafi->aafd->Identification.CompanyName && wcscmp( aafi->aafd->Identification.CompanyName, L"Digidesign, Inc." ) == 0 ) {
|
||||
// probe++;
|
||||
// }
|
||||
|
||||
if (aafi->aafd->Identification.ProductName && wcscmp (aafi->aafd->Identification.ProductName, L"ProTools") == 0) {
|
||||
if (aafi->aafd->Identification.CompanyName && strcmp (aafi->aafd->Identification.CompanyName, "Digidesign, Inc.") == 0) {
|
||||
probe++;
|
||||
}
|
||||
|
||||
if (probe == 1) {
|
||||
if (aafi->aafd->Identification.ProductName && strcmp (aafi->aafd->Identification.ProductName, "ProTools") == 0) {
|
||||
probe++;
|
||||
}
|
||||
|
||||
if (probe == 2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -105,131 +94,291 @@ protools_AAF (struct AAF_Iface* aafi)
|
|||
}
|
||||
|
||||
static int
|
||||
is_rendered_fade (const wchar_t* clipName)
|
||||
is_rendered_fade (const char* clipName)
|
||||
{
|
||||
return (memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_EN, PROTOOLS_CLIP_NAME_FADE_EN_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ES, PROTOOLS_CLIP_NAME_FADE_ES_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_FR, PROTOOLS_CLIP_NAME_FADE_FR_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ZH_CN, PROTOOLS_CLIP_NAME_FADE_ZH_CN_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ZH_TW, PROTOOLS_CLIP_NAME_FADE_ZH_TW_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_KO, PROTOOLS_CLIP_NAME_FADE_KO_LEN) == 0);
|
||||
return (strcmp (clipName, PROTOOLS_CLIP_NAME_FADE_EN) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ES) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_FADE_FR) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ZH_CN) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ZH_TW) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_FADE_KO) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
is_sample_accurate_edit (const wchar_t* clipName)
|
||||
is_sample_accurate_edit (const char* clipName)
|
||||
{
|
||||
return (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW_LEN) == 0) ||
|
||||
(memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO_LEN) == 0);
|
||||
return (strcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW) == 0) ||
|
||||
(strcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
replace_clipfade_with_fade (AAF_Iface* aafi, aafiTimelineItem* Item)
|
||||
remove_sampleAccurateEditClip (AAF_Iface* aafi, aafiAudioTrack* audioTrack, aafiTimelineItem* saeItem)
|
||||
{
|
||||
if (Item->type != AAFI_AUDIO_CLIP) {
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Note: In this function, we assume we need to expand a clip to remove an
|
||||
* attached sample accurate edit. TODO: Ensure it's always possible with ProTools
|
||||
*/
|
||||
|
||||
aafiAudioClip* audioClip = (aafiAudioClip*)Item->data;
|
||||
aafiAudioClip* saeClip = saeItem->data;
|
||||
|
||||
aafPosition_t currentpos = audioClip->pos;
|
||||
aafPosition_t currentlen = audioClip->len;
|
||||
if (saeItem->prev) {
|
||||
if (saeItem->prev->type == AAFI_AUDIO_CLIP) {
|
||||
aafiAudioClip* leftClip = saeItem->prev->data;
|
||||
|
||||
aafiTimelineItem* transItem = calloc (sizeof (aafiTimelineItem) + sizeof (aafiTransition), sizeof (char));
|
||||
if (saeClip->pos == (leftClip->pos + leftClip->len)) {
|
||||
aafPosition_t essenceLength = aafi_convertUnit (leftClip->essencePointerList->essenceFile->length, leftClip->essencePointerList->essenceFile->samplerateRational, leftClip->track->edit_rate);
|
||||
|
||||
memset (transItem, 0x00, sizeof (aafiTimelineItem) + sizeof (aafiTransition));
|
||||
if ((essenceLength - leftClip->essence_offset - leftClip->len) >= saeClip->len) {
|
||||
debug ("Removing SAE \"%s\" : left clip \"%s\" goes from length %" PRIi64 " to %" PRIi64,
|
||||
saeClip->essencePointerList->essenceFile->unique_name,
|
||||
leftClip->essencePointerList->essenceFile->unique_name,
|
||||
leftClip->len,
|
||||
leftClip->len + saeClip->len);
|
||||
|
||||
transItem->type = AAFI_TRANS;
|
||||
transItem->next = NULL;
|
||||
transItem->prev = NULL;
|
||||
leftClip->len += saeClip->len;
|
||||
|
||||
transItem->data = calloc (sizeof (aafiTransition), sizeof (char));
|
||||
aafi_removeTimelineItem (aafi, saeItem);
|
||||
|
||||
aafiTransition* trans = transItem->data;
|
||||
|
||||
trans->len = audioClip->len;
|
||||
trans->flags = AAFI_INTERPOL_NONE;
|
||||
|
||||
// debug( "%ls", audioClip->Essence->unique_file_name );
|
||||
|
||||
aafiAudioClip* prevClip = NULL;
|
||||
aafiAudioClip* nextClip = NULL;
|
||||
|
||||
if (Item->prev != NULL) {
|
||||
if (Item->prev->type == AAFI_AUDIO_CLIP) {
|
||||
prevClip = (aafiAudioClip*)Item->prev->data;
|
||||
|
||||
// debug( "PREVIOUS POS %lu", prevClip->pos + prevClip->len );
|
||||
// debug( "CURENT POS %lu", currentpos );
|
||||
|
||||
if (prevClip->pos + prevClip->len < currentpos - 1) {
|
||||
prevClip = NULL;
|
||||
audioTrack->clipCount--;
|
||||
return 1;
|
||||
}
|
||||
// else {
|
||||
// warning( L"Can't remove SAE \"%s\" : left clip \"%s\" has not enough right handle : %lu but %lu is required",
|
||||
// saeClip->essencePointerList->essenceFile->unique_name,
|
||||
// leftClip->essencePointerList->essenceFile->unique_name,
|
||||
// (essenceLength - leftClip->essence_offset - leftClip->len),
|
||||
// saeClip->len );
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Item->next != NULL) {
|
||||
if (Item->next->type == AAFI_AUDIO_CLIP) {
|
||||
nextClip = (aafiAudioClip*)Item->next->data;
|
||||
if (saeItem->next) {
|
||||
if (saeItem->next->type == AAFI_AUDIO_CLIP) {
|
||||
aafiAudioClip* rightClip = saeItem->next->data;
|
||||
|
||||
if (is_sample_accurate_edit (nextClip->essencePointerList->essence->file_name)) {
|
||||
if (Item->next->next != NULL) {
|
||||
nextClip = (aafiAudioClip*)Item->next->next->data;
|
||||
if ((saeClip->pos + saeClip->len) == rightClip->pos) {
|
||||
if (rightClip->essence_offset >= saeClip->len) {
|
||||
debug ("Removing SAE \"%s\" : right clip \"%s\" goes from length: %" PRIi64 " to %" PRIi64 ", pos: %" PRIi64 " to %" PRIi64 ", source offset: %" PRIi64 " to %" PRIi64,
|
||||
saeClip->essencePointerList->essenceFile->unique_name,
|
||||
rightClip->essencePointerList->essenceFile->unique_name,
|
||||
rightClip->len,
|
||||
rightClip->len + saeClip->len,
|
||||
rightClip->pos,
|
||||
rightClip->pos - saeClip->len,
|
||||
rightClip->essence_offset,
|
||||
rightClip->essence_offset - saeClip->len);
|
||||
|
||||
// debug( "NEXT POS %lu", nextClip->pos );
|
||||
// debug( "CURENT POS %lu", currentpos + currentlen );
|
||||
rightClip->pos -= saeClip->len;
|
||||
rightClip->len += saeClip->len;
|
||||
rightClip->essence_offset -= saeClip->len;
|
||||
|
||||
if (nextClip->pos != currentpos + currentlen + 1) {
|
||||
aafi_removeTimelineItem (aafi, saeItem);
|
||||
|
||||
audioTrack->clipCount--;
|
||||
return 1;
|
||||
}
|
||||
// else {
|
||||
// warning( L"Can't remove SAE \"%s\" : right clip \"%s\" has not enough left handle : %lu but %lu is required",
|
||||
// saeClip->essencePointerList->essenceFile->unique_name,
|
||||
// rightClip->essencePointerList->essenceFile->unique_name,
|
||||
// rightClip->essence_offset,
|
||||
// saeClip->len );
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
replace_clipFade (AAF_Iface* aafi, aafiAudioTrack* audioTrack, aafiTimelineItem* fadeItem)
|
||||
{
|
||||
aafiAudioClip* fadeClip = fadeItem->data;
|
||||
|
||||
aafiTimelineItem* prevItem1 = fadeItem->prev;
|
||||
aafiTimelineItem* prevItem2 = (prevItem1 && prevItem1->prev) ? prevItem1->prev : NULL;
|
||||
|
||||
aafiTimelineItem* nextItem1 = fadeItem->next;
|
||||
aafiTimelineItem* nextItem2 = (nextItem1 && nextItem1->next) ? nextItem1->next : NULL;
|
||||
|
||||
aafiAudioClip* prevClip = NULL;
|
||||
aafiAudioClip* nextClip = NULL;
|
||||
|
||||
if (prevItem1 && prevItem1->type == AAFI_AUDIO_CLIP) {
|
||||
prevClip = prevItem1->data;
|
||||
|
||||
if (fadeClip->pos == (prevClip->pos + prevClip->len)) {
|
||||
/* a previous clip is touching this fadeClip on the left */
|
||||
|
||||
if (is_sample_accurate_edit (prevClip->essencePointerList->essenceFile->name)) {
|
||||
remove_sampleAccurateEditClip (aafi, audioTrack, prevItem1);
|
||||
|
||||
if (prevItem2 && prevItem2->type == AAFI_AUDIO_CLIP) {
|
||||
aafiAudioClip* prevClip2 = prevItem2->data;
|
||||
|
||||
if (fadeClip->pos == (prevClip2->pos + prevClip2->len)) {
|
||||
prevClip = prevClip2;
|
||||
debug ("Got a clip \"%s\" preceding fadeClip \"%s\"",
|
||||
prevClip->essencePointerList->essenceFile->unique_name,
|
||||
fadeClip->essencePointerList->essenceFile->unique_name);
|
||||
} else {
|
||||
prevClip = NULL;
|
||||
}
|
||||
} else {
|
||||
prevClip = NULL;
|
||||
}
|
||||
} else {
|
||||
debug ("Got a clip \"%s\" preceding fadeClip \"%s\"",
|
||||
prevClip->essencePointerList->essenceFile->unique_name,
|
||||
fadeClip->essencePointerList->essenceFile->unique_name);
|
||||
}
|
||||
} else {
|
||||
prevClip = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextItem1 && nextItem1->type == AAFI_AUDIO_CLIP) {
|
||||
nextClip = nextItem1->data;
|
||||
|
||||
if ((fadeClip->pos + fadeClip->len) == nextClip->pos) {
|
||||
/* a following clip is touching this fadeClip on the right */
|
||||
|
||||
if (is_sample_accurate_edit (nextClip->essencePointerList->essenceFile->name)) {
|
||||
remove_sampleAccurateEditClip (aafi, audioTrack, nextItem1);
|
||||
|
||||
if (nextItem2 && nextItem2->type == AAFI_AUDIO_CLIP) {
|
||||
aafiAudioClip* nextClip2 = nextItem2->data;
|
||||
|
||||
if ((fadeClip->pos + fadeClip->len) == nextClip2->pos) {
|
||||
nextClip = nextClip2;
|
||||
debug ("Got a clip \"%s\" following fadeClip \"%s\"",
|
||||
nextClip->essencePointerList->essenceFile->unique_name,
|
||||
fadeClip->essencePointerList->essenceFile->unique_name);
|
||||
} else {
|
||||
nextClip = NULL;
|
||||
}
|
||||
} else {
|
||||
nextClip = NULL;
|
||||
}
|
||||
} else {
|
||||
// nextClip = (aafiAudioClip*)Item->next->data;
|
||||
|
||||
// debug( "NEXT POS %lu", nextClip->pos );
|
||||
// debug( "CURENT POS %lu", currentpos + currentlen );
|
||||
|
||||
if (nextClip->pos != currentpos + currentlen) {
|
||||
nextClip = NULL;
|
||||
}
|
||||
debug ("Got a clip \"%s\" following fadeClip \"%s\"",
|
||||
nextClip->essencePointerList->essenceFile->unique_name,
|
||||
fadeClip->essencePointerList->essenceFile->unique_name);
|
||||
}
|
||||
} else {
|
||||
nextClip = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!prevClip && !nextClip) {
|
||||
debug ("FadeClip \"%s\" is not surrounding by any touching clip",
|
||||
fadeClip->essencePointerList->essenceFile->unique_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensures we have enough handle in surrounding clips to expand by fade length
|
||||
*/
|
||||
|
||||
if (prevClip) {
|
||||
aafPosition_t essenceLength = aafi_convertUnit (prevClip->essencePointerList->essenceFile->length, prevClip->essencePointerList->essenceFile->samplerateRational, prevClip->track->edit_rate);
|
||||
|
||||
if ((essenceLength - prevClip->essence_offset - prevClip->len) < fadeClip->len) {
|
||||
warning ("Previous clip \"%s\" has not enough handle to build a fade in place of \"%s\"",
|
||||
prevClip->essencePointerList->essenceFile->unique_name,
|
||||
fadeClip->essencePointerList->essenceFile->unique_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextClip) {
|
||||
if (nextClip->essence_offset < fadeClip->len) {
|
||||
warning ("Next clip \"%s\" has not enough handle to build a fade in place of \"%s\"",
|
||||
nextClip->essencePointerList->essenceFile->unique_name,
|
||||
fadeClip->essencePointerList->essenceFile->unique_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
debug ("Replacing fadeClip \"%s\" with a %s transition of length %" PRIi64,
|
||||
fadeClip->essencePointerList->essenceFile->unique_name,
|
||||
(prevClip && nextClip) ? "X-Fade" : (nextClip) ? "FadeIn"
|
||||
: "FadeOut",
|
||||
fadeClip->len);
|
||||
|
||||
/*
|
||||
* changes existing aafiTimelineItem from aafiAudioClip into aafiTransition
|
||||
*/
|
||||
|
||||
aafPosition_t fadeClipLength = fadeClip->len;
|
||||
|
||||
fadeItem->type = AAFI_TRANS;
|
||||
|
||||
aafi_freeAudioClip (fadeItem->data);
|
||||
|
||||
fadeItem->data = calloc (1, sizeof (aafiTransition));
|
||||
|
||||
if (!fadeItem->data) {
|
||||
error ("Out of memory");
|
||||
aafi_removeTimelineItem (aafi, fadeItem);
|
||||
audioTrack->clipCount--;
|
||||
return 1; /* important ! */
|
||||
}
|
||||
|
||||
aafiTransition* trans = fadeItem->data;
|
||||
|
||||
trans->len = fadeClipLength;
|
||||
trans->flags = AAFI_INTERPOL_LINEAR;
|
||||
|
||||
trans->time_a = calloc (2, sizeof (aafRational_t));
|
||||
trans->value_a = calloc (2, sizeof (aafRational_t));
|
||||
|
||||
trans->time_a[0].numerator = 0;
|
||||
trans->time_a[0].denominator = 0;
|
||||
trans->time_a[1].numerator = 1;
|
||||
trans->time_a[1].denominator = 1;
|
||||
if (!trans->time_a || !trans->value_a) {
|
||||
error ("Out of memory");
|
||||
aafi_removeTimelineItem (aafi, fadeItem);
|
||||
audioTrack->clipCount--;
|
||||
return 1; /* important ! */
|
||||
}
|
||||
|
||||
if (prevClip && nextClip) {
|
||||
// debug( ":: XFADE" );
|
||||
prevClip->len += fadeClipLength;
|
||||
|
||||
nextClip->pos -= fadeClipLength;
|
||||
nextClip->len += fadeClipLength;
|
||||
nextClip->essence_offset -= fadeClipLength;
|
||||
|
||||
trans->flags |= AAFI_TRANS_XFADE;
|
||||
trans->cut_pt = fadeClipLength / 2;
|
||||
|
||||
trans->value_a[0].numerator = 0;
|
||||
trans->value_a[0].denominator = 0;
|
||||
trans->value_a[1].numerator = 1;
|
||||
trans->value_a[1].denominator = 1;
|
||||
} else if (prevClip) {
|
||||
// debug( ":: FADE OUT" );
|
||||
prevClip->len += fadeClipLength;
|
||||
|
||||
trans->flags |= AAFI_TRANS_FADE_OUT;
|
||||
trans->cut_pt = fadeClipLength;
|
||||
|
||||
trans->value_a[0].numerator = 1;
|
||||
trans->value_a[0].denominator = 1;
|
||||
trans->value_a[1].numerator = 0;
|
||||
trans->value_a[1].denominator = 0;
|
||||
} else if (nextClip) {
|
||||
// debug( ":: FADE IN" );
|
||||
nextClip->pos -= fadeClipLength;
|
||||
nextClip->len += fadeClipLength;
|
||||
nextClip->essence_offset -= fadeClipLength;
|
||||
|
||||
trans->flags |= AAFI_TRANS_FADE_IN;
|
||||
trans->cut_pt = 0;
|
||||
|
||||
trans->value_a[0].numerator = 0;
|
||||
trans->value_a[0].denominator = 0;
|
||||
|
|
@ -237,43 +386,23 @@ replace_clipfade_with_fade (AAF_Iface* aafi, aafiTimelineItem* Item)
|
|||
trans->value_a[1].denominator = 1;
|
||||
}
|
||||
|
||||
if (Item->prev) {
|
||||
Item->prev->next = transItem;
|
||||
transItem->prev = Item->prev;
|
||||
} else {
|
||||
aafiAudioTrack* audioTrack = NULL;
|
||||
audioTrack->clipCount--;
|
||||
|
||||
foreach_audioTrack (audioTrack, aafi)
|
||||
{
|
||||
if (audioTrack->Items == Item) {
|
||||
audioTrack->Items = transItem;
|
||||
}
|
||||
}
|
||||
|
||||
transItem->prev = NULL;
|
||||
}
|
||||
|
||||
if (Item->next) {
|
||||
Item->next->prev = transItem;
|
||||
}
|
||||
|
||||
transItem->next = Item->next;
|
||||
|
||||
aafi_freeTimelineItem (&Item);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
protools_post_processing (AAF_Iface* aafi /*, enum protools_options flags*/)
|
||||
protools_post_processing (AAF_Iface* aafi)
|
||||
{
|
||||
aafiAudioTrack* audioTrack = NULL;
|
||||
|
||||
foreach_audioTrack (audioTrack, aafi)
|
||||
AAFI_foreachAudioTrack (aafi, audioTrack)
|
||||
{
|
||||
aafiTimelineItem* audioItem = audioTrack->Items;
|
||||
aafiTimelineItem* audioItem = audioTrack->timelineItems;
|
||||
|
||||
while (audioItem != NULL) {
|
||||
aafiTimelineItem* audioItemNext = audioItem->next;
|
||||
|
||||
if (audioItem->type != AAFI_AUDIO_CLIP) {
|
||||
audioItem = audioItem->next;
|
||||
continue;
|
||||
|
|
@ -281,21 +410,23 @@ protools_post_processing (AAF_Iface* aafi /*, enum protools_options flags*/)
|
|||
|
||||
aafiAudioClip* audioClip = (aafiAudioClip*)audioItem->data;
|
||||
|
||||
wchar_t* clipName = audioClip->essencePointerList->essence->file_name;
|
||||
char* clipName = audioClip->essencePointerList->essenceFile->name;
|
||||
|
||||
if ((aafi->ctx.options.protools & PROTOOLS_REPLACE_CLIP_FADES) && is_rendered_fade (clipName)) {
|
||||
replace_clipfade_with_fade (aafi, audioItem);
|
||||
|
||||
audioItem = audioTrack->Items;
|
||||
continue;
|
||||
} else if ((aafi->ctx.options.protools & PROTOOLS_REMOVE_SAMPLE_ACCURATE_EDIT) && is_sample_accurate_edit (clipName)) {
|
||||
aafi_removeTimelineItem (aafi, audioItem);
|
||||
|
||||
audioItem = audioTrack->Items;
|
||||
continue;
|
||||
if ((aafi->ctx.options.protools & AAFI_PROTOOLS_OPT_REPLACE_CLIP_FADES) &&
|
||||
is_rendered_fade (clipName)) {
|
||||
if (replace_clipFade (aafi, audioTrack, audioItem) > 0) {
|
||||
audioItem = audioTrack->timelineItems;
|
||||
continue;
|
||||
}
|
||||
} else if ((aafi->ctx.options.protools & AAFI_PROTOOLS_OPT_REMOVE_SAMPLE_ACCURATE_EDIT) &&
|
||||
is_sample_accurate_edit (clipName)) {
|
||||
if (remove_sampleAccurateEditClip (aafi, audioTrack, audioItem)) {
|
||||
audioItem = audioTrack->timelineItems;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
audioItem = audioItem->next;
|
||||
audioItem = audioItemNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue