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

Reply via email to