On 07/11/2010 10:07 PM, Sebastian Vater wrote:
Michael Niedermayer a écrit :
i guess alot of these #defines could be enums and then the correct types
could be used instead of int*_t

[...]


Hi Michael! I will change them the next days, this will incorporate a
lot of changes to player.c also. Anyway, I have updated track.h, so new
patch attached anyway.

/*
 * AVSequencer track and pattern 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_TRACK_H
#define AVSEQUENCER_TRACK_H

#include "libavformat/avformat.h"
#include "libavsequencer/avsequencer.h"

/**
 * Song track data structure, This structure is actually for one row
 * and therefore actually pointed as an array with the amount of
 * rows of the whole track.
 * 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 AVSequencerTrackData {
    /** Array of pointers containing all effects used by this
       track.  */
    AVSequencerTrack **effects_data;

    /** Which octave the note is played upon, if note is a
       positive value (defaults to 4).  */
    uint8_t octave;
#define AVSEQ_TRACK_DATA_OCTAVE     4
#define AVSEQ_TRACK_DATA_OCTAVE_MIN 0
#define AVSEQ_TRACK_DATA_OCTAVE_MAX 9

Those MAX/MIN are characteristics of the player, no? So...

    /** Note to be played (see defines below, n is octave number).  */
    int8_t note;
    /** C-n  */
#define AVSEQ_TRACK_DATA_NOTE           1
#define AVSEQ_TRACK_DATA_NOTE_C         1
#define AVSEQ_TRACK_DATA_NOTE_MIN       AVSEQ_TRACK_DATA_NOTE_MIN

    /** C#n = Dbn  */
#define AVSEQ_TRACK_DATA_NOTE_C_SHARP   2

    /** D-n  */
#define AVSEQ_TRACK_DATA_NOTE_D         3

    /** D#n = Ebn  */
#define AVSEQ_TRACK_DATA_NOTE_D_SHARP   4

    /** E-n  */
#define AVSEQ_TRACK_DATA_NOTE_E         5

    /** F-n  */
#define AVSEQ_TRACK_DATA_NOTE_F         6

    /** F#n = Gbn  */
#define AVSEQ_TRACK_DATA_NOTE_F_SHARP   7

    /** G-n  */
#define AVSEQ_TRACK_DATA_NOTE_G         8

    /** G#n = Abn  */
#define AVSEQ_TRACK_DATA_NOTE_G_SHARP   9

    /** A-n  */
#define AVSEQ_TRACK_DATA_NOTE_A         10

    /** A#n = Bbn  */
#define AVSEQ_TRACK_DATA_NOTE_A_SHARP   11

    /** B-n = H-n  */
#define AVSEQ_TRACK_DATA_NOTE_B         12
#define AVSEQ_TRACK_DATA_NOTE_H         FF_AVSEQ_TRACK_DATA_NOTE_B
#define AVSEQ_TRACK_DATA_NOTE_MAX       FF_AVSEQ_TRACK_DATA_NOTE_B

    /** --- = first special empty note  */
#define AVSEQ_TRACK_DATA_NOTE_SPECIAL       0
#define AVSEQ_TRACK_DATA_NOTE_NONE          FF_AVSEQ_TRACK_DATA_NOTE_SPECIAL

    /** ^^^ = note kill  */
#define AVSEQ_TRACK_DATA_NOTE_KILL          -1

    /** ^^- = note off  */
#define AVSEQ_TRACK_DATA_NOTE_OFF           -2

    /** === = keyoff note  */
#define AVSEQ_TRACK_DATA_NOTE_KEYOFF        -3

    /** -|- = hold delay  */
#define AVSEQ_TRACK_DATA_NOTE_HOLD_DELAY    -4

    /** -\- = note fade  */
#define AVSEQ_TRACK_DATA_NOTE_FADE          -5

    /** END = pattern end marker  */
#define AVSEQ_TRACK_DATA_NOTE_END           -16

    /** Number of instrument to be played or 0 to take previous one.  */
    uint16_t instrument;

Why 0 to take previous one? This forces your array to start at 1 and IMHO does not simplify any code. In the player you can always do

if (instrument == previous_instrument) {...}

    /** C-4 = default tone  */
#define AVSEQ_TRACK_DATA_TONE               ((FF_AVSEQ_TRACK_DATA_OCTAVE << 8) 
| FF_AVSEQ_TRACK_DATA_NOTE)

    /** Number of effects used by this track.  */
    uint16_t effects;
} AVSequencerTrackData;

/**
 * Song track structure.
 * 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 AVSequencerTrack {
    /** Metadata information: Original track file name, track
       title, track message, track artist, track album,
       track begin and finish date of composition and comment.  */
    AVMetadata *metadata;

    /** AVSequencerTrackData pointer to array of track data.  */
    AVSequencerTrackData *data;

This naming bothers me a little. If AVSequencerTrackData contains the track data, what does AVSequencerTrack contains?

    /** Last valid row of track (defaults to 63 = 0x3F) which
       is the default for most trackers (64 rows per pattern).  */
    uint16_t last_row;
#define AVSEQ_TRACK_LAST_ROW    63
#define AVSEQ_TRACK_LENGTH      ((FF_AVSEQ_TRACK_LAST_ROW) + 1)
#define AVSEQ_TRACK_LENGTH_MIN  0
#define AVSEQ_TRACK_LENGTH_MAX  65536

    /** Track global volume (defaults to 255 = no volume scaling).  */
    uint8_t volume;
#define AVSEQ_TRACK_VOLUME  255

    /** Sub-volume level for this track. This is basically track
       global volume divided by 256, but the sub-volume doesn't
       account into actual mixer output (defaults 0).  */
    uint8_t sub_volume;
#define AVSEQ_TRACK_SUB_VOLUME  0

    /** Stereo panning level for this track (defaults to
       -128 = central stereo panning).  */
    int8_t panning;
#define AVSEQ_TRACK_PANNING -128

    /** Stereo track sub-panning level for this channel. This is
       basically track panning divided by 256, but the sub-panning
       doesn't account into actual mixer output (defaults 0).  */
    uint8_t sub_panning;
#define AVSEQ_TRACK_SUB_PANNING 0

    /** Track transpose. Add this value to octave * 12 + note to
       get the final octave / note played (defaults to 0).  */
    int8_t transpose;
#define AVSEQ_TRACK_TRANSPOSE   0

    /** Compatibility flags for playback. There are rare cases
       where track handling can not be mapped into internal
       playback engine and have to be handled specially. For
       each sub-song which needs this, this will define new
       flags which tag the player to handle it to that special
       way.  */
    uint8_t compat_flags;
#define AVSEQ_TRACK_COMPAT_FLAG_SAMPLE_OFFSET       0x01 ///< Sample offset 
beyond end of sample will be ignored (IT compatibility)
#define AVSEQ_TRACK_COMPAT_FLAG_TONE_PORTA          0x02 ///< Share tone 
portamento memory with portamentoes and unlock tone portamento samples and adjusts 
frequency to: new_freq = freq * new_rate / old_rate. If an instrument number is 
given the envelope will be retriggered (IT compatibility).
#define AVSEQ_TRACK_COMPAT_FLAG_SLIDES              0x04 ///< Portamentos of 
same type share the same memory (e.g. porta up/fine porta up)
#define AVSEQ_TRACK_COMPAT_FLAG_VOLUME_SLIDES       0x08 ///< All except 
portamento slides share the same memory (e.g. volume/panning slides)
#define AVSEQ_TRACK_COMPAT_FLAG_OP_SLIDES           0x10 ///< Oppositional 
portamento directions don't share the same memory (e.g. porta up and porta down)
#define AVSEQ_TRACK_COMPAT_FLAG_OP_VOLUME_SLIDES    0x20 ///< Oppositional 
non-portamento slide directions don't share the same memory
#define AVSEQ_TRACK_COMPAT_FLAG_VOLUME_PITCH        0x40 ///< Volume & pitch 
slides share same memory (S3M compatibility)

    /** Track playback flags. Some sequencers feature
       surround panning or allow initial reverse playback,
       different timing methods which have all to be taken
       care specially in the internal playback engine.  */
    uint8_t flags;
#define AVSEQ_TRACK_FLAG_USE_TIMING             0x01 ///< Use track timing 
fields
#define AVSEQ_TRACK_FLAG_SPD_TIMING             0x02 ///< SPD speed timing 
instead of BpM
#define AVSEQ_TRACK_FLAG_PANNING                0x04 ///< Use track panning and 
sub-panning fields
#define AVSEQ_TRACK_FLAG_SURROUND               0x08 ///< Use track surround 
panning
#define AVSEQ_TRACK_FLAG_REVERSE                0x10 ///< Playback of track in 
backward direction

    /** Initial number of frames per row, i.e. sequencer tempo
       (defaults to 6 as in most tracker formats).  */
    uint16_t frames;
#define AVSEQ_TRACK_FRAMES  6

    /** Initial speed multiplier, i.e. nominator which defaults
       to disabled = 0.  */
    uint8_t speed_mul;
#define AVSEQ_TRACK_SPEED_MUL   0

    /** Initial speed divider, i.e. denominator which defaults
       to disabled = 0.  */
    uint8_t speed_div;
#define AVSEQ_TRACK_SPEED_DIV   0

    /** Initial MED style SPD speed (defaults to 33 as in
       OctaMED Soundstudio).  */
    uint16_t spd_speed;
#define AVSEQ_TRACK_SPD_SPEED   33

    /** Initial number of rows per beat (defaults to 4 rows are a beat).  */
    uint16_t bpm_tempo;
#define AVSEQ_TRACK_BPM_TEMPO   4

    /** Initial beats per minute speed (defaults to 50 Hz => 125 BpM).  */
    uint16_t bpm_speed;
#define AVSEQ_SONG_BPM_SPEED   125

    /** 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 tracks in those chunks,
       which then won't get lost in that case.  */
    uint8_t **unknown_data;
} AVSequencerTrack;

/**
 * Song track effect structure, This structure is actually for one row
 * and therefore actually pointed as an array with the amount of
 * rows of the whole track.
 * 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 AVSequencerTrackEffect {

    /** Unused and reserved for future expansions, leave 0 for now.  */
    uint8_t reserved;

Can be removed.

    /** Effect command byte.  */
    uint8_t command;

    /** Command types.  */

Doxygen will not parse it as you want. Better just

/* Command types.  */

    /** Note effects (00-1F).  */
#define AVSEQ_TRACK_EFFECT_NOTE_MIN          0x00
#define AVSEQ_TRACK_EFFECT_NOTE_MAX          0x1F

    /** Volume control related effects (20-2F).  */
#define AVSEQ_TRACK_EFFECT_VOLUME_MIN        0x20
#define AVSEQ_TRACK_EFFECT_VOLUME_MAX        0x2F

    /** Panning control related effects (30-3F).  */
#define AVSEQ_TRACK_EFFECT_PANNING_MIN       0x30
#define AVSEQ_TRACK_EFFECT_PANNING_MAX       0x3F

    /** Track and channel control related effects (40-4F).  */
#define AVSEQ_TRACK_EFFECT_TRACK_MIN         0x40
#define AVSEQ_TRACK_EFFECT_TRACK_MAX         0x4F

    /** Instrument, sample and synth control related effects (50-5F).  */
#define AVSEQ_TRACK_EFFECT_INSTRUMENT_MIN    0x50
#define AVSEQ_TRACK_EFFECT_INSTRUMENT_MAX    0x5F

    /** Global control related effects (60-7E).  */
#define AVSEQ_TRACK_EFFECT_GLOBAL_MIN        0x60
#define AVSEQ_TRACK_EFFECT_GLOBAL_MAX        0x7E

This is ugly and fragile (what would you do if a new format shows up with a new volume effect). Why not an array instead?

static const Enum EffectType effect_type[AVSEQ_EFFECTS_NUMBER] = {
   [AVSEQ_TRACK_EFFECT_CMD_ARPEGGIO] = AVSEQ_TRACK_EFFECT_NOTE,
   [AVSEQ_TRACK_EFFECT_CMD_PORTA_UP] = AVSEQ_TRACK_EFFECT_NOTE,
   [...]
};

Note how easy would be change it to a struct to add more information about each effect.

BTW, using Arpeggio == 0x00 is specific for some format or some ad-hoc choice? If it is ad-hoc, it should not be part of the Doxy comment, it is not useful information.

    /** User customized effect for trigger in demos, etc.  */
#define AVSEQ_TRACK_EFFECT_USER              0x7F

    /** Note effect commands.
       0x00 - Arpeggio:
       Data word consists of two 8-bit pairs named xx and yy
       where xx is the first halftone and yy the second halftone.
       Both xx and yy are signed values which means that a
       negative value is a backward arpeggio.  */
#define AVSEQ_TRACK_EFFECT_CMD_ARPEGGIO      0x00

[...]

-Vitor
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to