Sebastian Vater a écrit :
> Vitor Sessak a écrit :
>
>> On 07/13/2010 11:13 PM, Sebastian Vater wrote:
>>
>>
>>> Original TuComposer didn't even use typedef's at all, the only way to
>>> access them was a struct TuComposerInstrEnvelope, etc.
>>>
>>> I also prefer the way to provide the target programmer more freedom than
>>> shrinking it, despite the fact that writing the header the way I did
>>> doesn't require much amount of time.
>>>
>>> This, however, is just a target-programmer-user-friendly purpose and
>>> wouldn't interfere with player.c by changing that, since I replaced all
>>> struct AVSequencer* with simply AVSequencer*
>>>
>>> However, changing that again, would require extra work by additionally
>>> making it a bit uncomfortable to target programmers. So if you are not
>>> piecy on this, I would keep is it at now, I will leave that decision
>>> completely to you, though. If you want me to remove that, I'll do.
>>>
>> Leave it as is. Maybe it is just my personal taste and not very
>> important ATM.
>>
>
> Ok. Updated patch though.
>
Hi I have excellent news!
libavsequencer now flawlessly integrates into FFmpeg, just check out my
latest git. Please do a git pull --rebase, Stefano had problems without
using it.
Here are the instr.[ch] part of the BSS to review.
This version compiles perfectly.
--
Best regards,
:-) Basty/CDGS (-:
diff --git a/libavsequencer/instr.c b/libavsequencer/instr.c
new file mode 100644
index 0000000..71dffe1
--- /dev/null
+++ b/libavsequencer/instr.c
@@ -0,0 +1,607 @@
+/*
+ * Implement AVSequencer instrument management
+ * Copyright (c) 2010 Sebastian Vater <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Implement AVSequencer instrument management.
+ */
+
+#include "libavutil/log.h"
+#include "libavsequencer/avsequencer.h"
+
+static const char *instrument_name(void *p)
+{
+ AVSequencerInstrument *instrument = p;
+ AVMetadataTag *tag = av_metadata_get(instrument->metadata, "title", NULL, AV_METADATA_IGNORE_SUFFIX);
+
+ return tag->value;
+}
+
+static const AVClass avseq_instrument_class = {
+ "AVSequencer Instrument",
+ instrument_name,
+ NULL,
+ LIBAVUTIL_VERSION_INT,
+};
+
+int avseq_instrument_open(AVSequencerModule *module, AVSequencerInstrument *instrument) {
+ AVSequencerSample *sample;
+ AVSequencerInstrument **instrument_list;
+ uint16_t instruments;
+ int res;
+
+ if (!module)
+ return AVERROR_INVALIDDATA;
+
+ instrument_list = module->instrument_list;
+ instruments = module->instruments;
+
+ if (!(instrument && ++instruments)) {
+ return AVERROR_INVALIDDATA;
+ } else if (!(instrument_list = av_realloc(instrument_list, instruments * sizeof(AVSequencerInstrument *)))) {
+ av_log(module, AV_LOG_ERROR, "cannot allocate instrument storage container.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ instrument->av_class = &avseq_instrument_class;
+
+ if (!(sample = avseq_sample_create())) {
+ av_free(instrument_list);
+ av_log(instrument, AV_LOG_ERROR, "cannot allocate first sample.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ instrument->fade_out = 65535;
+ instrument->pitch_pan_center = 4*12; // C-4
+ instrument->global_volume = 255;
+ instrument->default_panning = -128;
+ instrument->env_usage_flags = ~(AVSEQ_INSTRUMENT_FLAG_USE_VOLUME_ENV|AVSEQ_INSTRUMENT_FLAG_USE_PANNING_ENV|AVSEQ_INSTRUMENT_FLAG_USE_SLIDE_ENV|-0x2000);
+
+ if ((res = avseq_sample_open(instrument, sample, NULL, 0)) < 0) {
+ av_free(sample);
+ av_free(instrument_list);
+ return res;
+ }
+
+ instrument_list[instruments] = instrument;
+ module->instrument_list = instrument_list;
+ module->instruments = instruments;
+
+ return 0;
+}
+
+static const char *envelope_name(void *p)
+{
+ AVSequencerEnvelope *envelope = p;
+ AVMetadataTag *tag = av_metadata_get(envelope->metadata, "title", NULL, AV_METADATA_IGNORE_SUFFIX);
+
+ return tag->value;
+}
+
+static const AVClass avseq_envelope_class = {
+ "AVSequencer Envelope",
+ envelope_name,
+ NULL,
+ LIBAVUTIL_VERSION_INT,
+};
+
+#define CREATE_ENVELOPE(env_type) \
+ static void create_##env_type##_envelope ( AVSequencerContext *avctx, \
+ int16_t *data, \
+ uint32_t points, \
+ uint32_t scale, \
+ uint32_t scale_type, \
+ uint32_t y_offset )
+
+CREATE_ENVELOPE(empty);
+CREATE_ENVELOPE(sine);
+CREATE_ENVELOPE(cosine);
+CREATE_ENVELOPE(ramp);
+CREATE_ENVELOPE(triangle);
+CREATE_ENVELOPE(square);
+CREATE_ENVELOPE(sawtooth);
+
+static const void *create_env_lut[] = {
+ create_empty_envelope,
+ create_sine_envelope,
+ create_cosine_envelope,
+ create_ramp_envelope,
+ create_triangle_envelope,
+ create_square_envelope,
+ create_sawtooth_envelope
+};
+
+int avseq_envelope_open(AVSequencerContext *avctx, AVSequencerModule *module,
+ AVSequencerEnvelope *envelope, uint32_t points,
+ uint32_t type, uint32_t scale,
+ uint32_t y_offset, uint32_t nodes) {
+ AVSequencerEnvelope **envelope_list;
+ uint16_t envelopes;
+ int res;
+
+ if (!module)
+ return AVERROR_INVALIDDATA;
+
+ envelope_list = module->envelope_list;
+ envelopes = module->envelopes;
+
+ if (!(envelope && ++envelopes)) {
+ return AVERROR_INVALIDDATA;
+ } else if (!(envelope_list = av_realloc(envelope_list, envelopes * sizeof(AVSequencerEnvelope *)))) {
+ av_log(module, AV_LOG_ERROR, "cannot allocate envelope storage container.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ envelope->av_class = &avseq_envelope_class;
+ envelope->value_min = -scale;
+ envelope->value_max = scale;
+ envelope->tempo = 1;
+
+ if ((res = avseq_envelope_data_open(avctx, envelope, points, type, scale, y_offset, nodes)) < 0) {
+ av_free(envelope_list);
+ return res;
+ }
+
+ envelope_list[envelopes] = envelope;
+ module->envelope_list = envelope_list;
+ module->envelopes = envelopes;
+
+ return 0;
+}
+
+int avseq_envelope_data_open(AVSequencerContext *avctx, AVSequencerEnvelope *envelope,
+ uint32_t points, uint32_t type, uint32_t scale,
+ uint32_t y_offset, uint32_t nodes) {
+ uint32_t scale_type;
+ void (**create_env_func)( AVSequencerContext *avctx, int16_t *data, uint32_t points, uint32_t scale, uint32_t scale_type, uint32_t y_offset );
+ int16_t *data;
+
+ if (!envelope)
+ return AVERROR_INVALIDDATA;
+
+ data = envelope->data;
+
+ if (!(data = av_realloc(data, points * sizeof(int16_t)))) {
+ av_log(envelope, AV_LOG_ERROR, "cannot allocate envelope points.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ if (!points)
+ points = 64;
+
+ if (points >= 0x10000)
+ return AVERROR_INVALIDDATA;
+
+ scale_type = scale & 0x80000000;
+ scale &= 0x7FFFFFFF;
+
+ if (scale > 0x7FFF)
+ scale = 0x7FFF;
+
+ if (type > 6)
+ type = 0;
+
+ create_env_func = (void *) &(create_env_lut);
+ create_env_func[type] ( avctx, data, points, scale, scale_type, y_offset );
+
+ if (nodes) {
+ uint32_t node_div, node_mod, value = 0, count = 0, i;
+ uint16_t *node;
+
+ if (!nodes)
+ nodes = 12;
+
+ if (nodes == 1)
+ nodes++;
+
+ if (!(node = (uint16_t *) av_malloc(nodes * sizeof (uint16_t)))) {
+ av_free(data);
+ av_log(envelope, AV_LOG_ERROR, "cannot allocate envelope node data.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ envelope->node_points = node;
+ envelope->nodes = nodes;
+
+ if (nodes > points)
+ nodes = points;
+
+ node_div = points / nodes;
+ node_mod = points % nodes;
+
+ for (i = nodes; i > 0; i--) {
+ *node++ = value;
+
+ value += node_div;
+ count += node_mod;
+
+ if (count >= nodes) {
+ count -= nodes;
+ value++;
+ }
+ }
+
+ *--node = points - 1;
+ }
+
+ envelope->data = data;
+ envelope->points = points;
+
+ return 0;
+}
+
+CREATE_ENVELOPE(empty) {
+ uint32_t i;
+
+ for (i = points; i > 0; i--) {
+ *data++ = y_offset;
+ }
+}
+
+/** Sine table for very fast sine calculation. Value is
+ sin(x)*32767 with one element being one degree. */
+static const int16_t sine_lut[] = {
+ 0, 571, 1143, 1714, 2285, 2855, 3425, 3993, 4560, 5125, 5689, 6252, 6812, 7370, 7927, 8480,
+ 9031, 9580, 10125, 10667, 11206, 11742, 12274, 12803, 13327, 13847, 14364, 14875, 15383, 15885, 16383, 16876,
+ 17363, 17846, 18323, 18794, 19259, 19719, 20173, 20620, 21062, 21497, 21925, 22347, 22761, 23169, 23570, 23964,
+ 24350, 24729, 25100, 25464, 25820, 26168, 26509, 26841, 27165, 27480, 27787, 28086, 28377, 28658, 28931, 29195,
+ 29450, 29696, 29934, 30162, 30381, 30590, 30790, 30981, 31163, 31335, 31497, 31650, 31793, 31927, 32050, 32164,
+ 32269, 32363, 32448, 32522, 32587, 32642, 32687, 32722, 32747, 32762, 32767, 32762, 32747, 32722, 32687, 32642,
+ 32587, 32522, 32448, 32363, 32269, 32164, 32050, 31927, 31793, 31650, 31497, 31335, 31163, 30981, 30790, 30590,
+ 30381, 30162, 29934, 29696, 29450, 29195, 28931, 28658, 28377, 28086, 27787, 27480, 27165, 26841, 26509, 26168,
+ 25820, 25464, 25100, 24729, 24350, 23964, 23570, 23169, 22761, 22347, 21925, 21497, 21062, 20620, 20173, 19719,
+ 19259, 18794, 18323, 17846, 17363, 16876, 16383, 15885, 15383, 14875, 14364, 13847, 13327, 12803, 12274, 11742,
+ 11206, 10667, 10125, 9580, 9031, 8480, 7927, 7370, 6812, 6252, 5689, 5125, 4560, 3993, 3425, 2855,
+ 2285, 1714, 1143, 571, 0, -571, -1143, -1714, -2285, -2855, -3425, -3993, -4560, -5125, -5689, -6252,
+ -6812, -7370, -7927, -8480, -9031, -9580, -10125, -10667, -11206, -11742, -12274, -12803, -13327, -13847, -14364, -14875,
+ -15383, -15885, -16383, -16876, -17363, -17846, -18323, -18794, -19259, -19719, -20173, -20620, -21062, -21497, -21925, -22347,
+ -22761, -23169, -23570, -23964, -24350, -24729, -25100, -25464, -25820, -26168, -26509, -26841, -27165, -27480, -27787, -28086,
+ -28377, -28658, -28931, -29195, -29450, -29696, -29934, -30162, -30381, -30590, -30790, -30981, -31163, -31335, -31497, -31650,
+ -31793, -31927, -32050, -32164, -32269, -32363, -32448, -32522, -32587, -32642, -32687, -32722, -32747, -32762, -32767, -32762,
+ -32747, -32722, -32687, -32642, -32587, -32522, -32448, -32363, -32269, -32164, -32050, -31927, -31793, -31650, -31497, -31335,
+ -31163, -30981, -30790, -30590, -30381, -30162, -29934, -29696, -29450, -29195, -28931, -28658, -28377, -28086, -27787, -27480,
+ -27165, -26841, -26509, -26168, -25820, -25464, -25100, -24729, -24350, -23964, -23570, -23169, -22761, -22347, -21925, -21497,
+ -21062, -20620, -20173, -19719, -19259, -18794, -18323, -17846, -17363, -16876, -16383, -15885, -15383, -14875, -14364, -13847,
+ -13327, -12803, -12274, -11742, -11206, -10667, -10125, -9580, -9031, -8480, -7927, -7370, -6812, -6252, -5689, -5125,
+ -4560, -3993, -3425, -2855, -2285, -1714, -1143, -571
+};
+
+CREATE_ENVELOPE(sine) {
+ uint32_t i, sine_div, sine_mod, pos = 0, count = 0;
+ int32_t value = 0;
+ const int16_t *const lut = (avctx->sine_lut ? avctx->sine_lut : sine_lut);
+
+ sine_div = 360 / points;
+ sine_mod = 360 % points;
+
+ for (i = points; i > 0; i--) {
+ value = lut[pos];
+
+ if (scale_type)
+ value = -value;
+
+ pos += sine_div;
+ value *= (int32_t) scale;
+ value /= 32767;
+ value += y_offset;
+ count += sine_mod;
+
+ if (count >= points) {
+ count -= points;
+ pos++;
+ }
+
+ *data++ = value;
+ }
+}
+
+CREATE_ENVELOPE(cosine) {
+ uint32_t i, sine_div, sine_mod, count = 0;
+ int32_t pos = 90, value = 0;
+ const int16_t *const lut = (avctx->sine_lut ? avctx->sine_lut : sine_lut);
+
+ sine_div = 360 / points;
+ sine_mod = 360 % points;
+
+ for (i = points; i > 0; i--) {
+ value = lut[pos];
+
+ if (scale_type)
+ value = -value;
+
+ if ((pos -= sine_div) < 0)
+ pos += 360;
+
+ value *= (int32_t) scale;
+ value /= 32767;
+ value += y_offset;
+ count += sine_mod;
+
+ if (count >= points) {
+ count -= points;
+ pos--;
+
+ if (pos < 0)
+ pos += 360;
+ }
+
+ *data++ = value;
+ }
+}
+
+CREATE_ENVELOPE(ramp) {
+ uint32_t i, start_scale = -scale, ramp_points, scale_div, scale_mod, scale_count = 0, value;
+
+ if (!(ramp_points = points >> 1))
+ ramp_points = 1;
+
+ scale_div = scale / ramp_points;
+ scale_mod = scale % ramp_points;
+
+ for (i = points; i > 0; i--) {
+ value = start_scale;
+ start_scale += scale_div;
+ scale_count += scale_mod;
+
+ if (scale_count >= points) {
+ scale_count -= points;
+ start_scale++;
+ }
+
+ if (scale_type)
+ value = -value;
+
+ value += y_offset;
+ *data++ = value;
+ }
+}
+
+CREATE_ENVELOPE(square) {
+ unsigned i;
+ uint32_t j, value;
+
+ if (scale_type)
+ scale = -scale;
+
+ for (i = 2; i > 0; i--) {
+ scale = -scale;
+ value = (scale + y_offset);
+
+ for (j = points >> 1; j > 0; j--) {
+ *data++ = value;
+ }
+ }
+}
+
+CREATE_ENVELOPE(triangle) {
+ uint32_t i, value, pos = 0, down_pos, triangle_points, scale_div, scale_mod, scale_count = 0;
+
+ if (!(triangle_points = points >> 2))
+ triangle_points = 1;
+
+ scale_div = scale / triangle_points;
+ scale_mod = scale % triangle_points;
+ down_pos = points - triangle_points;
+
+ for (i = points; i > 0; i--) {
+ value = pos;
+
+ if (down_pos >= i) {
+ if (down_pos == i) {
+ scale_count += scale_mod;
+ scale_div = -scale_div;
+ }
+
+ if (triangle_points >= i) {
+ scale_count += scale_mod;
+ scale_div = -scale_div;
+ down_pos = 0;
+ }
+
+ pos += scale_div;
+ scale_count += scale_mod;
+
+ if (scale_count >= points) {
+ scale_count -= points;
+ pos--;
+ }
+ } else {
+ pos += scale_div;
+ scale_count += scale_mod;
+
+ if (scale_count >= points) {
+ scale_count -= points;
+ pos++;
+ }
+ }
+
+ if (scale_type)
+ value = -value;
+
+ value += y_offset;
+ *data++ = value;
+ }
+}
+
+CREATE_ENVELOPE(sawtooth) {
+ uint32_t i, value, pos = scale, down_pos, sawtooth_points, scale_div, scale_mod, scale_count = 0;
+
+ down_pos = points >> 1;
+
+ if (!(sawtooth_points = points >> 2))
+ sawtooth_points = 1;
+
+ scale_div = -(scale / sawtooth_points);
+ scale_mod = scale % sawtooth_points;
+
+ for (i = points; i > 0; i--) {
+ value = pos;
+
+ if (down_pos >= i) {
+ if (down_pos == i) {
+ scale_count += scale_mod;
+ scale_div = -scale_div;
+ }
+
+ pos += scale_div;
+ scale_count += scale_mod;
+
+ if (scale_count >= points) {
+ scale_count -= points;
+ pos++;
+ }
+ } else {
+ pos += scale_div;
+ scale_count += scale_mod;
+
+ if (scale_count >= points) {
+ scale_count -= points;
+ pos--;
+ }
+ }
+
+ if (scale_type)
+ value = -value;
+
+ value += y_offset;
+ *data++ = value;
+ }
+}
+
+static const char *keyboard_name(void *p)
+{
+ AVSequencerKeyboard *keyboard = p;
+ AVMetadataTag *tag = av_metadata_get(keyboard->metadata, "title", NULL, AV_METADATA_IGNORE_SUFFIX);
+
+ return tag->value;
+}
+
+static const AVClass avseq_keyboard_class = {
+ "AVSequencer Keyboard",
+ keyboard_name,
+ NULL,
+ LIBAVUTIL_VERSION_INT,
+};
+
+int avseq_keyboard_open(AVSequencerModule *module, AVSequencerKeyboard *keyboard) {
+ AVSequencerKeyboard **keyboard_list;
+ uint16_t keyboards;
+ unsigned i;
+
+ if (!module)
+ return AVERROR_INVALIDDATA;
+
+ keyboard_list = module->keyboard_list;
+ keyboards = module->keyboards;
+
+ if (!(keyboard && ++keyboards)) {
+ return AVERROR_INVALIDDATA;
+ } else if (!(keyboard_list = av_realloc(keyboard_list, keyboards * sizeof(AVSequencerKeyboard *)))) {
+ av_log(module, AV_LOG_ERROR, "cannot allocate keyboard definition list storage container.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ keyboard->av_class = &avseq_keyboard_class;
+
+ for (i = 0; i < 120; ++i) {
+ keyboard->key[i].sample = 0;
+ keyboard->key[i].octave = i / 12;
+ keyboard->key[i].note = (i % 12) + 1;
+ }
+
+ keyboard_list[keyboards] = keyboard;
+ module->keyboard_list = keyboard_list;
+ module->keyboards = keyboards;
+
+ return 0;
+}
+
+static const char *arpeggio_name(void *p)
+{
+ AVSequencerArpeggio *arpeggio = p;
+ AVMetadataTag *tag = av_metadata_get(arpeggio->metadata, "title", NULL, AV_METADATA_IGNORE_SUFFIX);
+
+ return tag->value;
+}
+
+static const AVClass avseq_arpeggio_class = {
+ "AVSequencer Arpeggio",
+ arpeggio_name,
+ NULL,
+ LIBAVUTIL_VERSION_INT,
+};
+
+int avseq_arpeggio_open(AVSequencerModule *module, AVSequencerArpeggio *arpeggio,
+ uint32_t entries) {
+ AVSequencerArpeggio **arpeggio_list;
+ uint16_t arpeggios;
+ int res;
+
+ if (!module)
+ return AVERROR_INVALIDDATA;
+
+ arpeggio_list = module->arpeggio_list;
+ arpeggios = module->arpeggios;
+
+ if (!(arpeggio && ++arpeggios)) {
+ return AVERROR_INVALIDDATA;
+ } else if (!(arpeggio_list = av_realloc(arpeggio_list, arpeggios * sizeof(AVSequencerArpeggio *)))) {
+ av_log(module, AV_LOG_ERROR, "cannot allocate arpeggio structure storage container.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ arpeggio->av_class = &avseq_arpeggio_class;
+
+ if ((res = avseq_arpeggio_data_open(arpeggio, entries)) < 0) {
+ av_free(arpeggio_list);
+ return res;
+ }
+
+ arpeggio_list[arpeggios] = arpeggio;
+ module->arpeggio_list = arpeggio_list;
+ module->arpeggios = arpeggios;
+
+ return 0;
+}
+
+int avseq_arpeggio_data_open(AVSequencerArpeggio *arpeggio, uint32_t entries) {
+ AVSequencerArpeggioData *data;
+
+ if (!arpeggio)
+ return AVERROR_INVALIDDATA;
+
+ data = arpeggio->data;
+
+ if (!entries)
+ entries = 3;
+
+ if (entries >= 0x10000) {
+ return AVERROR_INVALIDDATA;
+ } else if (!(data = av_realloc(data, entries * sizeof(AVSequencerArpeggioData)))) {
+ av_log(arpeggio, AV_LOG_ERROR, "cannot allocate arpeggio structure data.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ arpeggio->data = data;
+ arpeggio->entries = entries;
+
+ return 0;
+}
diff --git a/libavsequencer/instr.h b/libavsequencer/instr.h
new file mode 100755
index 0000000..1a1eede
--- /dev/null
+++ b/libavsequencer/instr.h
@@ -0,0 +1,571 @@
+/*
+ * AVSequencer instrument management
+ * Copyright (c) 2010 Sebastian Vater <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVSEQUENCER_INSTR_H
+#define AVSEQUENCER_INSTR_H
+
+#include "libavutil/log.h"
+#include "libavformat/avformat.h"
+
+/** AVSequencerEnvelope->flags bitfield. */
+enum AVSequencerEnvelopeFlags {
+ AVSEQ_ENVELOPE_LOOP = 0x0001, ///< Envelope uses loop nodes
+ AVSEQ_ENVELOPE_SUSTAIN = 0x0002, ///< Envelope uses sustain nodes
+ AVSEQ_ENVELOPE_PINGPONG = 0x0004, ///< Envelope loop is in ping pong mode
+ AVSEQ_ENVELOPE_SUSTAIN_PINGPONG = 0x0008, ///< Envelope sustain loop is in ping pong mode
+};
+
+/**
+ * Envelope structure used by instruments to apply volume / panning
+ * or pitch manipulation according to an user defined waveform.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ */
+typedef struct AVSequencerEnvelope {
+ /**
+ * information on struct for av_log
+ * - set by avseq_alloc_context
+ */
+ const AVClass *av_class;
+
+ /** Metadata information: Original envelope file name, envelope
+ * name, artist and comment. */
+ AVMetadata *metadata;
+
+ /** The actual node data of this envelope as signed 16-bit integer.
+ For a volume envelope, we have a default scale range of -32767
+ to +32767, for panning envelopes the scale range is between -8191
+ to +8191. For slide, vibrato, tremolo, pannolo (and their auto
+ versions), the scale range is between -256 to +256. */
+ int16_t *data;
+
+ /** The node points values or 0 if the envelope is empty. */
+ uint16_t *node_points;
+
+ /** Number of dragable nodes of this envelope (defaults to 12). */
+ uint16_t nodes;
+
+ /** Number of envelope points, i.e. node data values which
+ defaults to 64. */
+ uint16_t points;
+
+ /** Instrument envelope flags. Some sequencers feature
+ loop points of various kinds, which have to be taken
+ care specially in the internal playback engine. */
+ uint16_t flags;
+
+ /** Envelope tempo in ticks (defaults to 1, i.e. change envelope
+ at every frame / tick). */
+ uint16_t tempo;
+
+ /** Envelope sustain loop start point. */
+ uint16_t sustain_start;
+
+ /** Envelope sustain loop end point. */
+ uint16_t sustain_end;
+
+ /** Envelope sustain loop repeat counter for loop range. */
+ uint16_t sustain_count;
+
+ /** Envelope loop repeat start point. */
+ uint16_t loop_start;
+
+ /** Envelope loop repeat end point. */
+ uint16_t loop_end;
+
+ /** Envelope loop repeat counter for loop range. */
+ uint16_t loop_count;
+
+ /** Randomized lowest value allowed. */
+ int16_t value_min;
+
+ /** Randomized highest value allowed. */
+ int16_t value_max;
+
+ /** Array of pointers containing every unknown data field where
+ the last element is indicated by a NULL pointer reference. The
+ first 64-bit of the unknown data contains an unique identifier
+ for this chunk and the second 64-bit data is actual unsigned
+ length of the following raw data. Some formats are chunk based
+ and can store information, which can't be handled by some
+ other, in case of a transition the unknown data is kept as is.
+ Some programs write editor settings for envelopes in those
+ chunks, which then won't get lost in that case. */
+ uint8_t **unknown_data;
+} AVSequencerEnvelope;
+
+/**
+ * Keyboard definitions structure used by instruments to map
+ * note to samples. C-0 is first key. B-9 is 120th key.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ */
+typedef struct AVSequencerKeyboard {
+ /**
+ * information on struct for av_log
+ * - set by avseq_alloc_context
+ */
+ const AVClass *av_class;
+
+ /** Metadata information: Original keyboard file name, keyboard
+ * name, artist and comment. */
+ AVMetadata *metadata;
+
+ struct AVSequencerKeyboardEntry {
+ /** Sample number for this keyboard note. */
+ uint16_t sample;
+
+ /** Octave value for this keyboard note. */
+ uint8_t octave;
+
+ /** Note value for this keyboard note. */
+ uint8_t note;
+ } key[120];
+} AVSequencerKeyboard;
+
+/**
+ * Arpeggio data structure, This structure is actually for one tick
+ * and therefore actually pointed as an array with the amount of
+ * different ticks handled by the arpeggio control.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ */
+typedef struct AVSequencerArpeggioData {
+ /** Packed note or 0 if this is an arpeggio note. */
+ uint8_t tone;
+
+ /** Transpose for this arpeggio tick. */
+ int8_t transpose;
+
+ /** Instrument number to switch to or 0 for original instrument. */
+ uint16_t instrument;
+
+ /** The four effect command bytes which are executed. */
+ uint8_t command[4];
+
+ /** The four data word values of the four effect command bytes. */
+ uint16_t data[4];
+} AVSequencerArpeggioData;
+
+/** AVSequencerArpeggio->flags bitfield. */
+enum AVSequencerArpeggioFlags {
+ AVSEQ_ARPEGGIO_FLAG_LOOP = 0x0001, ///< Arpeggio control is looped
+ AVSEQ_ARPEGGIO_FLAG_SUSTAIN = 0x0002, ///< Arpeggio control has a sustain loop
+ AVSEQ_ARPEGGIO_FLAG_PINGPONG = 0x0004, ///< Arpeggio control will be looped in ping pong mpde
+ AVSEQ_ARPEGGIO_FLAG_SUSTAIN_PINGPONG = 0x0008, ///< Arpeggio control will have sustain loop ping pong mode enabled
+};
+
+/**
+ * Arpeggio control envelope used by all instrumental stuff.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ */
+typedef struct AVSequencerArpeggio {
+ /**
+ * information on struct for av_log
+ * - set by avseq_alloc_context
+ */
+ const AVClass *av_class;
+
+ /** Metadata information: Original arpeggio file name, arpeggio
+ * name, artist and comment. */
+ AVMetadata *metadata;
+
+ /** AVSequencerArpeggioData pointer to arpeggio data structure. */
+ AVSequencerArpeggioData *data;
+
+ /** Instrument arpeggio control flags. Some sequencers feature
+ customized arpeggio command control.which have to be taken
+ care specially in the internal playback engine. */
+ uint16_t flags;
+
+ /** Number of arpeggio ticks handled by this arpeggio control
+ (defaults to 3 points as in normal arpeggio command). */
+ uint16_t entries;
+
+ /** Sustain loop start tick of arpeggio control. */
+ uint16_t sustain_start;
+
+ /** Sustain loop end tick of arpeggio control. */
+ uint16_t sustain_end;
+
+ /** Sustain loop count number of how often to repeat loop
+ of arpeggio control. */
+ uint16_t sustain_count;
+
+ /** Loop start tick of arpeggio control. */
+ uint16_t loop_start;
+
+ /** Loop end tick of arpeggio control. */
+ uint16_t loop_end;
+
+ /** Loop count number of how often to repeat loop of arpeggio
+ control. */
+ uint16_t loop_count;
+} AVSequencerArpeggio;
+
+/** AVSequencerInstrument->nna values. */
+enum AVSequencerInstrumentNNA {
+ AVSEQ_INSTRUMENT_NNA_NOTE_CUT = 0x00, ///< Cut previous note
+ AVSEQ_INSTRUMENT_NNA_NOTE_CONTINUE = 0x01, ///< Continue previous note
+ AVSEQ_INSTRUMENT_NNA_NOTE_OFF = 0x02, ///< Perform key-off on previous note
+ AVSEQ_INSTRUMENT_NNA_NOTE_FADE = 0x03, ///< Perform fadeout on previous note
+};
+
+/** AVSequencerInstrument->dct values. */
+enum AVSequencerInstrumentDCT {
+ AVSEQ_INSTRUMENT_DCT_INSTR_NOTE_OR = 0x01, ///< Check for duplicate OR instrument notes
+ AVSEQ_INSTRUMENT_DCT_SAMPLE_NOTE_OR = 0x02, ///< Check for duplicate OR sample notes
+ AVSEQ_INSTRUMENT_DCT_INSTR_OR = 0x04, ///< Check for duplicate OR instruments
+ AVSEQ_INSTRUMENT_DCT_SAMPLE_OR = 0x08, ///< Check for duplicate OR samples
+ AVSEQ_INSTRUMENT_DCT_INSTR_NOTE_AND = 0x10, ///< Check for duplicate AND instrument notes
+ AVSEQ_INSTRUMENT_DCT_SAMPLE_NOTE_AND = 0x20, ///< Check for duplicate AND sample notes
+ AVSEQ_INSTRUMENT_DCT_INSTR_AND = 0x40, ///< Check for duplicate AND instruments
+ AVSEQ_INSTRUMENT_DCT_SAMPLE_AND = 0x80, ///< Check for duplicate AND samples
+};
+
+/** AVSequencerInstrument->dna values. */
+enum AVSequencerInstrumentDNA {
+ AVSEQ_INSTRUMENT_DNA_NOTE_CUT = 0x00, ///< Do note cut on duplicate note
+ AVSEQ_INSTRUMENT_DNA_NOTE_OFF = 0x01, ///< Perform keyoff on duplicate note
+ AVSEQ_INSTRUMENT_DNA_NOTE_FADE = 0x02, ///< Fade off notes on duplicate note
+ AVSEQ_INSTRUMENT_DNA_NOTE_CONTINUE = 0x03, ///< Nothing (only useful for synth sound handling)
+};
+
+/** AVSequencerInstrument->compat_flags bitfield. */
+enum AVSequencerInstrumentCompatFlags {
+ AVSEQ_INSTRUMENT_COMPAT_FLAG_LOCK_INSTR_WAVE = 0x01, ///< Instrument wave is locked as in MOD, but volume / panning / etc. is taken, if both bits are clear it will handle like S3M/IT, i.e. instrument is changed
+ AVSEQ_INSTRUMENT_COMPAT_FLAG_AFFECT_CHANNEL_PAN = 0x02, ///< Instrument panning affects channel panning (IT compatibility)
+ AVSEQ_INSTRUMENT_COMPAT_FLAG_PREV_SAMPLE = 0x04, ///< If no sample in keyboard definitions, use previous one
+ AVSEQ_INSTRUMENT_COMPAT_FLAG_SEPARATE_SAMPLES = 0x08, ///< Use absolute instead of relative sample values (IT compatibility)
+};
+
+/** AVSequencerInstrument->flags bitfield. */
+enum AVSequencerInstrumentFlags {
+ AVSEQ_INSTRUMENT_FLAG_NO_TRANSPOSE = 0x01, ///< Instrument can't be transpoed by the order list
+ AVSEQ_INSTRUMENT_FLAG_PORTA_SLIDE_ENV = 0x02, ///< Slide envelopes will be portamento values, otherwise transpose + finetune
+ AVSEQ_INSTRUMENT_FLAG_LINEAR_SLIDE_ENV = 0x04, ///< Use linear freqency table for slide envelope for portamento mode
+ AVSEQ_INSTRUMENT_FLAG_DEFAULT_PANNING = 0x10, ///< Use instrument panning and override sample default panning
+ AVSEQ_INSTRUMENT_FLAG_SURROUND_PANNING = 0x20, ///< Use surround sound as default instrument panning
+ AVSEQ_INSTRUMENT_FLAG_NO_INSTR_TRANSPOSE = 0x40, ///< Order instrument transpose doesn't apply to this instrument
+};
+
+/** AVSequencerInstrument->env_usage_flags bitfield. */
+enum AVSequencerInstrumentEnvUsageFlags {
+ AVSEQ_INSTRUMENT_FLAG_USE_VOLUME_ENV = 0x0001, ///< Use (reload) volume envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_PANNING_ENV = 0x0002, ///< Use (reload) panning envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_SLIDE_ENV = 0x0004, ///< Use (reload) slide envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_VIBRATO_ENV = 0x0008, ///< Use (reload) vibrato envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_TREMOLO_ENV = 0x0010, ///< Use (reload) tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_PANNOLO_ENV = 0x0020, ///< Use (reload) pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_CHANNOLO_ENV = 0x0040, ///< Use (reload) channolo envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_SPENOLO_ENV = 0x0080, ///< Use (reload) spenolo envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_TRACK_TREMOLO_ENV = 0x0100, ///< Use (reload) track tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_TRACK_PANNOLO_ENV = 0x0200, ///< Use (reload) track pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_GLOBAL_TREMOLO_ENV = 0x0400, ///< Use (reload) global tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_GLOBAL_PANNOLO_ENV = 0x0800, ///< Use (reload) global pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_USE_RESONANCE_ENV = 0x1000, ///< Use (reload) resonance filter
+};
+
+/** AVSequencerInstrument->env_proc_flags bitfield. */
+enum AVSequencerInstrumentEnvProcFlags {
+ AVSEQ_INSTRUMENT_FLAG_PROC_VOLUME_ENV = 0x0001, ///< Add first, then get volume envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_PANNING_ENV = 0x0002, ///< Add first, then get panning envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_SLIDE_ENV = 0x0004, ///< Add first, then get slide envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_VIBRATO_ENV = 0x0008, ///< Add first, then get vibrato envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_TREMOLO_ENV = 0x0010, ///< Add first, then get tremolo envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_PANNOLO_ENV = 0x0020, ///< Add first, then get pannolo envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_CHANNOLO_ENV = 0x0040, ///< Add first, then get channolo envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_SPENOLO_ENV = 0x0080, ///< Add first, then get spenolo envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_TRACK_TREMOLO_ENV = 0x0100, ///< Add first, then get track tremolo envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_TRACK_PANNOLO_ENV = 0x0200, ///< Add first, then get track pannolo envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_GLOBAL_TREMOLO_ENV = 0x0400, ///< Add first, then get global tremolo envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_GLOBAL_PANNOLO_ENV = 0x0800, ///< Add first, then get global pannolo envelope value
+ AVSEQ_INSTRUMENT_FLAG_PROC_RESONANCE_ENV = 0x1000, ///< Add first, then get resonance filter value
+};
+
+/** AVSequencerInstrument->env_retrig_flags bitfield. */
+enum AVSequencerInstrumentEnvRetrigFlags {
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_VOLUME_ENV = 0x0001, ///< Not retrigger volume envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_PANNING_ENV = 0x0002, ///< Not retrigger panning envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_SLIDE_ENV = 0x0004, ///< Not retrigger slide envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_VIBRATO_ENV = 0x0008, ///< Not retrigger vibrato envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_TREMOLO_ENV = 0x0010, ///< Not retrigger tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_PANNOLO_ENV = 0x0020, ///< Not retrigger pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_CHANNOLO_ENV = 0x0040, ///< Not retrigger channolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_SPENOLO_ENV = 0x0080, ///< Not retrigger spenolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_TRACK_TREMOLO_ENV = 0x0100, ///< Not retrigger track tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_TRACK_PANNOLO_ENV = 0x0200, ///< Not retrigger track pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_GLOBAL_TREMOLO_ENV = 0x0400, ///< Not retrigger global tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_GLOBAL_PANNOLO_ENV = 0x0800, ///< Not retrigger global pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RETRIG_RESONANCE_ENV = 0x1000, ///< Not retrigger resonance filter
+};
+
+/** AVSequencerInstrument->env_random_flags bitfield. */
+enum AVSequencerInstrumentEnvRandomFlags {
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_VOLUME_ENV = 0x0001, ///< Randomize volume envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_PANNING_ENV = 0x0002, ///< Randomize panning envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_SLIDE_ENV = 0x0004, ///< Randomize slide envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_VIBRATO_ENV = 0x0008, ///< Randomize vibrato envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_TREMOLO_ENV = 0x0010, ///< Randomize tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_PANNOLO_ENV = 0x0020, ///< Randomize pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_CHANNOLO_ENV = 0x0040, ///< Randomize channolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_SPENOLO_ENV = 0x0080, ///< Randomize spenolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_TRACK_TREMOLO_ENV = 0x0100, ///< Randomize track tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_TRACK_PANNOLO_ENV = 0x0200, ///< Randomize track pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_GLOBAL_TREMOLO_ENV = 0x0400, ///< Randomize global tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_GLOBAL_PANNOLO_ENV = 0x0800, ///< Randomize global pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RANDOM_RESONANCE_ENV = 0x1000, ///< Randomize resonance filter
+};
+
+/** AVSequencerInstrument->env_rnd_delay_flags bitfield. */
+enum AVSequencerInstrumentEnvRndDelayFlags {
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_VOLUME_ENV = 0x0001, ///< Speed is randomized delay for volume envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_PANNING_ENV = 0x0002, ///< Speed is randomized delay for panning envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_SLIDE_ENV = 0x0004, ///< Speed is randomized delay for slide envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_VIBRATO_ENV = 0x0008, ///< Speed is randomized delay for vibrato envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_TREMOLO_ENV = 0x0010, ///< Speed is randomized delay for tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_PANNOLO_ENV = 0x0020, ///< Speed is randomized delay for pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_CHANNOLO_ENV = 0x0040, ///< Speed is randomized delay for channolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_SPENOLO_ENV = 0x0080, ///< Speed is randomized delay for spenolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_TRACK_TREMOLO_ENV = 0x0100, ///< Speed is randomized delay for track tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_TRACK_PANNOLO_ENV = 0x0200, ///< Speed is randomized delay for track pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_GLOBAL_TREMOLO_ENV = 0x0400, ///< Speed is randomized delay for global tremolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_GLOBAL_PANNOLO_ENV = 0x0800, ///< Speed is randomized delay for global pannolo envelope
+ AVSEQ_INSTRUMENT_FLAG_RND_DELAY_RESONANCE_ENV = 0x1000, ///< Speed is randomized delay for resonance filter
+};
+
+/** AVSequencerInstrument->midi_flags bitfield. */
+enum AVSequencerInstrumentMIDIFlags {
+ AVSEQ_INSTRUMENT_FLAG_MIDI_TICK_QUANTIZE = 0x01, ///< Tick quantize (insert note delays)
+ AVSEQ_INSTRUMENT_FLAG_MIDI_NOTE_OFF = 0x02, ///< Record note off (keyoff note)
+ AVSEQ_INSTRUMENT_FLAG_MIDI_VELOCITY = 0x04, ///< Record velocity
+ AVSEQ_INSTRUMENT_FLAG_MIDI_AFTER_TOUCH = 0x08, ///< Record after touch
+ AVSEQ_INSTRUMENT_FLAG_MIDI_EXTERNAL_SYNC = 0x10, ///< External synchronization when recording
+ AVSEQ_INSTRUMENT_FLAG_MIDI_ENABLE = 0x80, ///< MIDI enabled
+};
+
+#include "libavsequencer/sample.h"
+
+/**
+ * Instrument structure used by all instrumental stuff.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ */
+typedef struct AVSequencerInstrument {
+ /**
+ * information on struct for av_log
+ * - set by avseq_alloc_context
+ */
+ const AVClass *av_class;
+
+ /** Metadata information: Original instrument file name, instrument
+ * name, artist and comment. */
+ AVMetadata *metadata;
+
+ /** Array (of size samples) of pointers containing every sample
+ used by this instrument. */
+ AVSequencerSample **sample_list;
+
+ /** Number of samples associated with this instrument
+ (a maximum number of 255 attached samples is allowed).
+ The default is one attached sample. */
+ uint8_t samples;
+
+ /** Pointer to envelope data interpreted as volume control
+ or NULL if volume envelope control is not used. */
+ AVSequencerEnvelope *volume_env;
+
+ /** Pointer to envelope data interpreted as panning control
+ or NULL if panning envelope control is not used. */
+ AVSequencerEnvelope *panning_env;
+
+ /** Pointer to envelope data interpreted as pitch and slide
+ control or NULL if slide envelope control is not used. */
+ AVSequencerEnvelope *slide_env;
+
+ /** Pointer to envelope data interpreted as vibrato waveform
+ control or NULL if vibrato envelope is not used. */
+ AVSequencerEnvelope *vibrato_env;
+
+ /** Pointer to envelope data interpreted as tremolo waveform
+ control or NULL if tremolo envelope is not used. */
+ AVSequencerEnvelope *tremolo_env;
+
+ /** Pointer to envelope data interpreted as pannolo / panbrello
+ waveform control or NULL if pannolo envelope is not used. */
+ AVSequencerEnvelope *pannolo_env;
+
+ /** Pointer to envelope data interpreted as channolo waveform
+ control or NULL if channolo envelope is not used. */
+ AVSequencerEnvelope *channolo_env;
+
+ /** Pointer to envelope data interpreted as spenolo waveform
+ control or NULL if spenolo envelope is not used. */
+ AVSequencerEnvelope *spenolo_env;
+
+ /** Pointer to envelope data interpreted as resonance filter
+ control or NULL if resonance filter is unused. */
+ AVSequencerEnvelope *resonance_env;
+
+ /** Pointer to arpeggio control structure to be used for custom
+ apreggios or NULL if this instrument uses standard
+ arpeggio behaviour. */
+ AVSequencerArpeggio *arpeggio_ctrl;
+
+ /** Pointer to instrument keyboard definitions which maps
+ the octave/instrument-pair to an associated sample. */
+ AVSequencerKeyboard *keyboard_defs;
+
+ /** Global volume scaling instrument samples. */
+ uint8_t global_volume;
+
+ /** NNA (New Note Action) mode. */
+ uint8_t nna;
+
+ /** Random note swing in semi-tones. This value will cause
+ a flip between each play of this instrument making it
+ sounding more natural. */
+ uint8_t note_swing;
+
+ /** Random volume swing in 1/256th steps (i.e. 256 means 100%).
+ The volume will vibrate randomnessly around that volume
+ percentage and make the instrument sound more like a
+ natural playing. */
+ uint16_t volume_swing;
+
+ /** Random panning swing, will cause the stereo position to
+ vary a bit each instrument play to make it sound more naturally
+ played. */
+ uint16_t panning_swing;
+
+ /** Random pitch swing in 1/65536th steps, i.e. 65536 means 100%. */
+ uint32_t pitch_swing;
+
+ /** Pitch panning separation. */
+ int16_t pitch_pan_separation;
+
+ /** Default panning for all samples. */
+ uint8_t default_panning;
+
+ /** Default sub-panning for all samples. */
+ uint8_t default_sub_pan;
+
+ /** Duplicate note check type. */
+ uint8_t dct;
+
+ /** Duplicate note check action. */
+ uint8_t dna;
+
+ /** Compatibility flags for playback. There are rare cases
+ where instrument to sample mapping has to be handled
+ a different way, or a different policy for no sample
+ specified cases. */
+ uint8_t compat_flags;
+
+ /** Instrument playback flags. Some sequencers feature
+ surround panning or allow different types of envelope
+ interpretations, differend types of slides which have to
+ be taken care specially in the internal playback engine. */
+ uint8_t flags;
+
+ /** Envelope usage flags. Some sequencers feature
+ reloading of envelope data when a new note is played. */
+ uint16_t env_usage_flags;
+
+ /** Envelope processing flags. Some sequencers differ in the
+ way how they handle envelopes. Some first increment
+ envelope node and then get the data and some do first
+ get the data and then increment the envelope data. */
+ uint16_t env_proc_flags;
+
+ /** Envelope retrigger flags. Some sequencers differ in the
+ way how they handle envelopes restart. Some continue
+ the previous instrument envelope when an new instrument
+ does not define an envelope, others disable this
+ envelope instead. */
+ uint16_t env_retrig_flags;
+
+ /** Envelope randomize flags. Some sequencers allow to use
+ data from a pseudo random number generator. If the
+ approciate bit is set, the envelope data will be
+ randomized each access. */
+ uint16_t env_random_flags;
+
+ /** Envelope randomize delay flags. Some sequencers allow
+ to specify a time interval when a new random value
+ can be read. */
+ uint16_t env_rnd_delay_flags;
+
+ /** Fade out value which defaults to 65535 (full volume level as in XM). */
+ uint16_t fade_out;
+
+ /** Hold value. */
+ uint16_t hold;
+
+ /** Decay value. */
+ uint16_t decay;
+
+ /** Decay action when decay is off. */
+ uint8_t dca;
+
+ /** Pitch panning center (0 is C-0, 1 is C#1, 12 is C-1, 13 is C#1,
+ 24 is C-2, 36 is C-3 and so on. Defaults to 48 = C-4). */
+ uint8_t pitch_pan_center;
+
+ /** MIDI channel this instrument is associated with. */
+ uint8_t midi_channel;
+
+ /** MIDI program (instrument) this instrument maps to. */
+ uint8_t midi_program;
+
+ /** MIDI flags. Some sequencers allow general MIDI support
+ and can play certain instruments directly through a MIDI
+ channel. */
+ uint8_t midi_flags;
+
+ /** MIDI transpose (in half-tones). */
+ int8_t midi_transpose;
+
+ /** MIDI after touch percentage. */
+ uint8_t midi_after_touch;
+
+ /** MIDI pitch bender (in half-tones). */
+ uint8_t midi_pitch_bender;
+
+ /** Array of pointers containing every unknown data field where
+ the last element is indicated by a NULL pointer reference. The
+ first 64-bit of the unknown data contains an unique identifier
+ for this chunk and the second 64-bit data is actual unsigned
+ length of the following raw data. Some formats are chunk based
+ and can store information, which can't be handled by some
+ other, in case of a transition the unknown data is kept as is.
+ Some programs write editor settings for instruments in those
+ chunks, which then won't get lost in that case. */
+ uint8_t **unknown_data;
+} AVSequencerInstrument;
+
+#endif /* AVSEQUENCER_INSTR_H */
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc