81 lines
2.9 KiB
C
81 lines
2.9 KiB
C
|
|
#include "../project/project_internal.h"
|
||
|
|
#include <math.h>
|
||
|
|
#include <string.h>
|
||
|
|
static size_t find_track(const xtc_project *p, uint64_t id)
|
||
|
|
{
|
||
|
|
size_t i;
|
||
|
|
for (i = 0; i < p->track_count; ++i)
|
||
|
|
if (p->tracks[i].id == id)
|
||
|
|
return i;
|
||
|
|
return SIZE_MAX;
|
||
|
|
}
|
||
|
|
xtc_result xtc_project_set_mix(xtc_project *p, uint64_t id, float gain, float pan, int mute,
|
||
|
|
int solo)
|
||
|
|
{
|
||
|
|
size_t i;
|
||
|
|
if (!p || !isfinite(gain) || gain < 0 || gain > 4 || !isfinite(pan) || pan < -1 || pan > 1 ||
|
||
|
|
(mute != 0 && mute != 1) || (solo != 0 && solo != 1))
|
||
|
|
return XTC_ERR_INVALID_ARGUMENT;
|
||
|
|
i = find_track(p, id);
|
||
|
|
if (i == SIZE_MAX)
|
||
|
|
return XTC_ERR_NOT_FOUND;
|
||
|
|
p->tracks[i].gain = gain;
|
||
|
|
p->tracks[i].pan = pan;
|
||
|
|
p->tracks[i].mute = mute;
|
||
|
|
p->tracks[i].solo = solo;
|
||
|
|
return XTC_OK;
|
||
|
|
}
|
||
|
|
xtc_result xtc_project_set_automation(xtc_project *p, const xtc_automation_point *a)
|
||
|
|
{
|
||
|
|
size_t i;
|
||
|
|
if (!p || !a || !isfinite(a->value) || a->tick > XTC_PROJECT_MAX_TICK ||
|
||
|
|
(a->parameter != XTC_AUTOMATION_GAIN && a->parameter != XTC_AUTOMATION_PAN) ||
|
||
|
|
a->value < (a->parameter == XTC_AUTOMATION_GAIN ? 0 : -1) ||
|
||
|
|
a->value > (a->parameter == XTC_AUTOMATION_GAIN ? 4 : 1))
|
||
|
|
return XTC_ERR_INVALID_ARGUMENT;
|
||
|
|
if (find_track(p, a->track_id) == SIZE_MAX)
|
||
|
|
return XTC_ERR_NOT_FOUND;
|
||
|
|
for (i = 0; i < p->automation_count; ++i)
|
||
|
|
if (p->automation[i].track_id == a->track_id &&
|
||
|
|
p->automation[i].parameter == a->parameter && p->automation[i].tick == a->tick)
|
||
|
|
break;
|
||
|
|
if (i == XTC_MAX_AUTOMATION_POINTS)
|
||
|
|
return XTC_ERR_CAPACITY;
|
||
|
|
if (i == p->automation_count)
|
||
|
|
++p->automation_count;
|
||
|
|
p->automation[i] = *a;
|
||
|
|
return XTC_OK;
|
||
|
|
}
|
||
|
|
xtc_result xtc_project_remove_automation(xtc_project *p, uint64_t id,
|
||
|
|
xtc_automation_parameter param, uint64_t tick)
|
||
|
|
{
|
||
|
|
size_t i;
|
||
|
|
if (!p || (param != XTC_AUTOMATION_GAIN && param != XTC_AUTOMATION_PAN) ||
|
||
|
|
tick > XTC_PROJECT_MAX_TICK)
|
||
|
|
return XTC_ERR_INVALID_ARGUMENT;
|
||
|
|
for (i = 0; i < p->automation_count; ++i)
|
||
|
|
if (p->automation[i].track_id == id && p->automation[i].parameter == param &&
|
||
|
|
p->automation[i].tick == tick)
|
||
|
|
break;
|
||
|
|
if (i == p->automation_count)
|
||
|
|
return XTC_ERR_NOT_FOUND;
|
||
|
|
memmove(p->automation + i, p->automation + i + 1,
|
||
|
|
(--p->automation_count - i) * sizeof(*p->automation));
|
||
|
|
return XTC_OK;
|
||
|
|
}
|
||
|
|
xtc_result xtc_project_automation_count(const xtc_project *p, size_t *n)
|
||
|
|
{
|
||
|
|
if (!p || !n)
|
||
|
|
return XTC_ERR_INVALID_ARGUMENT;
|
||
|
|
*n = p->automation_count;
|
||
|
|
return XTC_OK;
|
||
|
|
}
|
||
|
|
xtc_result xtc_project_get_automation(const xtc_project *p, size_t i, xtc_automation_point *a)
|
||
|
|
{
|
||
|
|
if (!p || !a)
|
||
|
|
return XTC_ERR_INVALID_ARGUMENT;
|
||
|
|
if (i >= p->automation_count)
|
||
|
|
return XTC_ERR_NOT_FOUND;
|
||
|
|
*a = p->automation[i];
|
||
|
|
return XTC_OK;
|
||
|
|
}
|