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