mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 08:36:32 +01:00
Import libAAF into Ardour's source-tree
tools/update_libaaf.sh - libaaf v0.1-85-g3e4c2cd
This commit is contained in:
parent
47e437c2aa
commit
7593551e49
48 changed files with 24378 additions and 0 deletions
303
libs/aaf/ProTools.c
Normal file
303
libs/aaf/ProTools.c
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
* Copyright (C) 2017-2023 Adrien Gesta-Fline
|
||||
*
|
||||
* This file is part of libAAF.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#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";
|
||||
/* French : "Fondu " */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_FADE_FR[] = L"\x0046\x006f\x006e\x0064\x0075\x0020\x0000";
|
||||
/* 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";
|
||||
/* Korean : "페이드" */
|
||||
static const wchar_t PROTOOLS_CLIP_NAME_FADE_KO[] = L"\xd398\xc774\xb4dc\x0000";
|
||||
|
||||
/* 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";
|
||||
/* 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";
|
||||
/* 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";
|
||||
/* 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";
|
||||
/* 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";
|
||||
/* 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 int
|
||||
is_rendered_fade (const wchar_t* clipName);
|
||||
static int
|
||||
is_sample_accurate_edit (const wchar_t* clipName);
|
||||
static int
|
||||
replace_clipfade_with_fade (AAF_Iface* aafi, aafiTimelineItem* Item);
|
||||
|
||||
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 ? */
|
||||
|
||||
// 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) {
|
||||
probe++;
|
||||
}
|
||||
|
||||
if (probe == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
is_rendered_fade (const wchar_t* 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);
|
||||
}
|
||||
|
||||
static int
|
||||
is_sample_accurate_edit (const wchar_t* 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);
|
||||
}
|
||||
|
||||
static int
|
||||
replace_clipfade_with_fade (AAF_Iface* aafi, aafiTimelineItem* Item)
|
||||
{
|
||||
if (Item->type != AAFI_AUDIO_CLIP) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
aafiAudioClip* audioClip = (aafiAudioClip*)Item->data;
|
||||
|
||||
aafPosition_t currentpos = audioClip->pos;
|
||||
aafPosition_t currentlen = audioClip->len;
|
||||
|
||||
aafiTimelineItem* transItem = calloc (sizeof (aafiTimelineItem) + sizeof (aafiTransition), sizeof (char));
|
||||
|
||||
memset (transItem, 0x00, sizeof (aafiTimelineItem) + sizeof (aafiTransition));
|
||||
|
||||
transItem->type = AAFI_TRANS;
|
||||
transItem->next = NULL;
|
||||
transItem->prev = NULL;
|
||||
|
||||
transItem->data = calloc (sizeof (aafiTransition), sizeof (char));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Item->next != NULL) {
|
||||
if (Item->next->type == AAFI_AUDIO_CLIP) {
|
||||
nextClip = (aafiAudioClip*)Item->next->data;
|
||||
|
||||
if (is_sample_accurate_edit (nextClip->Essence->file_name)) {
|
||||
if (Item->next->next != NULL) {
|
||||
nextClip = (aafiAudioClip*)Item->next->next->data;
|
||||
|
||||
// debug( "NEXT POS %lu", nextClip->pos );
|
||||
// debug( "CURENT POS %lu", currentpos + currentlen );
|
||||
|
||||
if (nextClip->pos != currentpos + currentlen + 1) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (prevClip && nextClip) {
|
||||
// debug( ":: XFADE" );
|
||||
trans->flags |= AAFI_TRANS_XFADE;
|
||||
|
||||
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" );
|
||||
trans->flags |= AAFI_TRANS_FADE_OUT;
|
||||
|
||||
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" );
|
||||
trans->flags |= AAFI_TRANS_FADE_IN;
|
||||
|
||||
trans->value_a[0].numerator = 0;
|
||||
trans->value_a[0].denominator = 0;
|
||||
trans->value_a[1].numerator = 1;
|
||||
trans->value_a[1].denominator = 1;
|
||||
}
|
||||
|
||||
if (Item->prev) {
|
||||
Item->prev->next = transItem;
|
||||
transItem->prev = Item->prev;
|
||||
} else {
|
||||
aafiAudioTrack* audioTrack = NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
protools_post_processing (AAF_Iface* aafi /*, enum protools_options flags*/)
|
||||
{
|
||||
aafiAudioTrack* audioTrack = NULL;
|
||||
|
||||
foreach_audioTrack (audioTrack, aafi)
|
||||
{
|
||||
aafiTimelineItem* audioItem = audioTrack->Items;
|
||||
|
||||
while (audioItem != NULL) {
|
||||
if (audioItem->type != AAFI_AUDIO_CLIP) {
|
||||
audioItem = audioItem->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
aafiAudioClip* audioClip = (aafiAudioClip*)audioItem->data;
|
||||
|
||||
wchar_t* clipName = audioClip->Essence->file_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;
|
||||
}
|
||||
|
||||
audioItem = audioItem->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue