Sebastian Vater a écrit :
> Updated patch.
>
>
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 sample.[ch] part of the BSS to review.
This version compiles perfectly.
--
Best regards,
:-) Basty/CDGS (-:
diff --git a/libavsequencer/sample.c b/libavsequencer/sample.c
new file mode 100644
index 0000000..8eddfd8
--- /dev/null
+++ b/libavsequencer/sample.c
@@ -0,0 +1,108 @@
+/*
+ * Implement AVSequencer samples 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 samples management.
+ */
+
+#include "libavutil/log.h"
+#include "libavsequencer/avsequencer.h"
+
+static const char *sample_name(void *p)
+{
+ AVSequencerSample *sample = p;
+ AVMetadataTag *tag = av_metadata_get(sample->metadata, "title", NULL, AV_METADATA_IGNORE_SUFFIX);
+
+ return tag->value;
+}
+
+static const AVClass avseq_sample_class = {
+ "AVSequencer Sample",
+ sample_name,
+ NULL,
+ LIBAVUTIL_VERSION_INT,
+};
+
+AVSequencerSample *avseq_sample_create(void) {
+ return av_mallocz(sizeof(AVSequencerSample));
+}
+
+int avseq_sample_open(AVSequencerInstrument *instrument, AVSequencerSample *sample,
+ int16_t *data, uint32_t length) {
+ AVSequencerSample **sample_list;
+ uint8_t samples;
+ int res;
+
+ if (!instrument)
+ return AVERROR_INVALIDDATA;
+
+ sample_list = instrument->sample_list;
+ samples = instrument->samples;
+
+ if (!(sample && ++samples)) {
+ return AVERROR_INVALIDDATA;
+ } else if (!(sample_list = av_realloc(sample_list, samples * sizeof(AVSequencerSample *)))) {
+ av_log(instrument, AV_LOG_ERROR, "cannot allocate sample storage container.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ sample->av_class = &avseq_sample_class;
+ sample->bits_per_sample = 16;
+ sample->rate = 8363; // NTSC frequency (60 Hz sequencers), for PAL use 8287
+ sample->rate_max = 0xFFFFFFFF;
+ sample->global_volume = 255;
+ sample->volume = 255;
+ sample->panning = -128;
+
+ if (length && (res = avseq_sample_data_open(sample, data, length)) < 0) {
+ av_free(sample_list);
+ return res;
+ }
+
+ sample_list[samples] = sample;
+ instrument->sample_list = sample_list;
+ instrument->samples = samples;
+
+ return 0;
+}
+
+int avseq_sample_data_open(AVSequencerSample *sample, int16_t *data, uint32_t samples) {
+ uint32_t size;
+
+ if (!sample)
+ return AVERROR_INVALIDDATA;
+
+ size = FFALIGN(samples * sample->bits_per_sample, 8) >> 3;
+
+ if (data) {
+ sample->flags = AVSEQ_SAMPLE_FLAG_REDIRECT;
+ } else if (!(data = av_mallocz(size))) {
+ av_log(sample, AV_LOG_ERROR, "cannot allocate sample data.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ sample->data = data;
+ sample->size = size;
+ sample->samples = samples;
+
+ return 0;
+}
diff --git a/libavsequencer/sample.h b/libavsequencer/sample.h
new file mode 100755
index 0000000..2da365f
--- /dev/null
+++ b/libavsequencer/sample.h
@@ -0,0 +1,302 @@
+/*
+ * AVSequencer samples 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_SAMPLE_H
+#define AVSEQUENCER_SAMPLE_H
+
+#include "libavutil/log.h"
+#include "libavformat/avformat.h"
+#include "libavsequencer/synth.h"
+
+/** AVSequencerSample->compat_flags bitfield. */
+enum AVSequencerSampleCompatFlags {
+ AVSEQ_SAMPLE_COMPAT_FLAG_AFFECT_CHANNEL_PAN = 0x01, ///< Sample panning affects channel panning (IT compatibility)
+ AVSEQ_SAMPLE_COMPAT_FLAG_VOLUME_ONLY = 0x02, ///< If a note without a sample is played, only the sample volume will be left unchanged
+ AVSEQ_SAMPLE_COMPAT_FLAG_START_TONE_PORTAMENTO = 0x04, ///< If a tone portamento with a note is executed but no note is currently played, the tone portamento will be ignored and start playing the note normally
+ AVSEQ_SAMPLE_COMPAT_FLAG_PLAY_BEGIN_TONE_PORTA = 0x08, ///< If you change a sample within a tone portamento the sample will be played from beginning
+};
+
+/** AVSequencerSample->flags bitfield. */
+enum AVSequencerSampleFlags {
+ AVSEQ_SAMPLE_FLAG_REDIRECT = 0x01, ///< Sample is a redirection (symbolic link)
+ AVSEQ_SAMPLE_FLAG_LOOP = 0x02, ///< Use normal loop points
+ AVSEQ_SAMPLE_FLAG_SUSTAIN_LOOP = 0x04, ///< Use sustain loop points
+ AVSEQ_SAMPLE_FLAG_SAMPLE_PANNING = 0x08, ///< Use sample panning
+ AVSEQ_SAMPLE_FLAG_SURROUND_PANNING = 0x10, ///< Sample panning is surround panning
+ AVSEQ_SAMPLE_FLAG_REVERSE = 0x40, ///< Sample will be initially played backwards
+};
+
+/** AVSequencerSample->repeat_mode bitfield. */
+enum AVSequencerSampleRepMode {
+ AVSEQ_SAMPLE_REP_MODE_BACKWARDS = 0x01, ///< Use always backward instead of always forward loop
+ AVSEQ_SAMPLE_REP_MODE_PINGPONG = 0x02, ///< Use ping-pong loop mode, i.e. forward <-> backward
+};
+
+/** AVSequencerSample->sustain_repeat_mode bitfield. */
+enum AVSequencerSampleSustainRepMode {
+ AVSEQ_SAMPLE_SUSTAIN_REP_MODE_BACKWARDS = 0x01, ///< Use always backward instead of always forward loop
+ AVSEQ_SAMPLE_SUSTAIN_REP_MODE_PINGPONG = 0x02, ///< Use ping-pong loop mode, i.e. forward <-> backward
+};
+
+/** AVSequencerSample->env_usage_flags bitfield. */
+enum AVSequencerSampleEnvUsageFlags {
+ AVSEQ_SAMPLE_FLAG_USE_AUTO_VIBRATO_ENV = 0x01, ///< Use (reload) auto vibrato envelope
+ AVSEQ_SAMPLE_FLAG_USE_AUTO_TREMOLO_ENV = 0x02, ///< Use (reload) auto tremolo envelope
+ AVSEQ_SAMPLE_FLAG_USE_AUTO_PANNOLO_ENV = 0x04, ///< Use (reload) auto pannolo envelope
+};
+
+/** AVSequencerSample->env_proc_flags bitfield. */
+enum AVSequencerSampleEnvProcFlags {
+ AVSEQ_SAMPLE_FLAG_PROC_AUTO_VIBRATO_ENV = 0x01, ///< Add first, then get auto vibrato envelope value
+ AVSEQ_SAMPLE_FLAG_PROC_AUTO_TREMOLO_ENV = 0x02, ///< Add first, then get auto tremolo envelope value
+ AVSEQ_SAMPLE_FLAG_PROC_AUTO_PANNOLO_ENV = 0x04, ///< Add first, then get auto pannolo envelope value
+ AVSEQ_SAMPLE_FLAG_PROC_LINEAR_AUTO_VIB = 0x80, ///< Use linear frequency table for auto vibrato
+};
+
+/** AVSequencerSample->env_retrig_flags bitfield. */
+enum AVSequencerSampleEnvRetrigFlags {
+ AVSEQ_SAMPLE_FLAG_RETRIG_AUTO_VIBRATO_ENV = 0x01, ///< Not retrigger auto vibrato envelope
+ AVSEQ_SAMPLE_FLAG_RETRIG_AUTO_TREMOLO_ENV = 0x02, ///< Not retrigger auto tremolo envelope
+ AVSEQ_SAMPLE_FLAG_RETRIG_AUTO_PANNOLO_ENV = 0x04, ///< Not retrigger auto pannolo envelope
+};
+
+/** AVSequencerSample->env_random_flags bitfield. */
+enum AVSequencerSampleEnvRandomFlags {
+ AVSEQ_SAMPLE_FLAG_RANDOM_AUTO_VIBRATO_ENV = 0x01, ///< Randomize auto vibrato envelope
+ AVSEQ_SAMPLE_FLAG_RANDOM_AUTO_TREMOLO_ENV = 0x02, ///< Randomize auto tremolo envelope
+ AVSEQ_SAMPLE_FLAG_RANDOM_AUTO_PANNOLO_ENV = 0x04, ///< Randomize auto pannolo envelope
+};
+
+/**
+ * Sample structure used by all instruments which are either
+ * have samples attached or are hybrids.
+ * 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 AVSequencerSample {
+ /**
+ * information on struct for av_log
+ * - set by avseq_alloc_context
+ */
+ const AVClass *av_class;
+
+ /** Metadata information: Original sample file name, sample name,
+ * artist and comment. */
+ AVMetadata *metadata;
+
+ /** AVSequencerSynth pointer to synth sound structure or NULL
+ if this is neither a synth nor a hybrid. */
+ AVSequencerSynth *synth;
+
+ /** Pointer to raw sample data, must be padded for
+ perfect perfomance gain when accessing sample data.
+ This can be NULL in case if this is a MIDI instrument
+ or a synth sound instead. */
+ int16_t *data;
+
+ /** Number of bytes the raw sample data occupies. 0 for
+ MIDI instruments and synth sounds. */
+ uint32_t size;
+
+ /** Number of samples of the raw sample data or 0 for
+ MIDI instruments and synth sounds. */
+ uint32_t samples;
+
+ /** Sample repeat starting loop point. If looping is enabled, this
+ will be used as restart point. */
+ uint32_t repeat;
+
+ /** Sample repeat length. End loop point is repeat + rep_len. */
+ uint32_t rep_len;
+
+ /** Sample repeat count. Some sequencers allow to not only define
+ an infinite repeat count but specify that more precisely.
+ In that case, set this to a non zero value indicating the
+ number of loop counts. */
+ uint32_t rep_count;
+
+ /** Sample sustain repeat starting loop point. If sustain looping is
+ enabled, this will be used as sustain restart point.
+ Sustain loop is triggered by a note keyoff event. */
+ uint32_t sustain_repeat;
+
+ /** Sample sustain repeat length. End sustain loop point is
+ sustain_repeat + sustain_rep_len. */
+ uint32_t sustain_rep_len;
+
+ /** Sample sustain repeat count. Some sequencers allow to not only
+ define an infinite sustain repeat count but specify that more
+ precisely. In that case, this has to be set to a non-zero value
+ indicating the number of sustain loop counts. */
+ uint32_t sustain_rep_count;
+
+ /** Sampling rate (frequency) in Hz to play C-4 at which defaults
+ to 8363 (NTSC base frequency used by 60Hz sequencers). */
+ uint32_t rate;
+
+ /** Lower sample rate limit (the sample can never exceed this
+ minimum allowed frequency rate during playback). */
+ uint32_t rate_min;
+
+ /** Upper sample rate limit (the sample can never exceed this
+ maximum allowed frequency rate during playback). */
+ uint32_t rate_max;
+
+ /** Initial sample offset to start playback at (usually 0). */
+ uint32_t start_offset;
+
+ /** Sample bit depth (currently samples having bit depths from
+ 1 to 32 are supported, default is 8-bit sample). */
+ uint8_t bits_per_sample;
+
+ /** Sample transpose. This is a relative number of half-tones to
+ be added to the note calculation (defaults to 0). */
+ int8_t transpose;
+
+ /** Sample fine-tuning control. This is a relative number in
+ one of 128th a half-tone for fine sampling rate adjustments
+ (default is 0 = no fine-tuning). */
+ int8_t finetune;
+
+ /** Compatibility flags for playback. There are rare cases
+ where sample loop control has to be handled a different
+ way, or a different policy for no sample specified cases. */
+ uint8_t compat_flags;
+
+ /** Sample playback flags. Some sequencers feature
+ surround panning or allow different types of loop control
+ differend types of frequency tables which have to be taken
+ care specially in the internal playback engine. */
+ uint8_t flags;
+
+ /** Sample repeat mode. Some sequencers allow to define
+ different loop modes. There is a normal forward loop mode,
+ a normal backward loop and a ping-pong loop mode (switch
+ between forward and backward looping each touch of loop
+ points). */
+ uint8_t repeat_mode;
+
+ /** Sample sustain loop mode. Some sequencers allow to define
+ different loop types. There is a normal forward sustain loop
+ mode, a normal backward sustain loop and a ping-pong sustain
+ loop mode (switch between forward and backward looping each
+ touch of sustain loop points). */
+ uint8_t sustain_repeat_mode;
+
+ /** Sample global volume. This will scale all volume operations
+ of this sample (default is 255 = no scaling). */
+ uint8_t global_volume;
+
+ /** Sample initial volume (defaults to 255 = maximum). */
+ uint8_t volume;
+
+ /** Sub-volume level for this sample. This is basically sample
+ volume divided by 256, but the sub-volume doesn't
+ account into actual mixer output (defaults to 0). */
+ uint8_t sub_volume;
+
+ /** Stereo panning level for this sample (defaults to
+ -128 = central stereo panning) if instrument panning
+ is not used. */
+ int8_t panning;
+
+ /** Stereo sub-panning level for this sample. This is
+ basically sample panning divided by 256, but the sub-panning
+ doesn't account into actual mixer output (defaults 0). */
+ uint8_t sub_panning;
+
+ /** Pointer to envelope data interpreted as auto vibrato
+ waveform control or NULL for turn off auto vibrato. */
+ AVSequencerEnvelope *auto_vibrato_env;
+
+ /** Pointer to envelope data interpreted as auto tremolo
+ waveform control or NULL for turn off auto tremolo. */
+ AVSequencerEnvelope *auto_tremolo_env;
+
+ /** Pointer to envelope data interpreted as auto pannolo
+ waveform control or NULL for turn off auto pannolo. */
+ AVSequencerEnvelope *auto_pannolo_env;
+
+ /** Auto vibrato / tremolo / pannolo envelope usage flags.
+ Some sequencers feature reloading of envelope data when
+ a new note is played. */
+ uint8_t env_usage_flags;
+
+ /** Auto vibrato / tremolo / pannolo envelope processing flags.
+ Sequencers differ in the way how they handle envelopes.
+ Some first increment envelope node and then get the data and
+ others first get the data and then increment the envelope data. */
+ uint8_t env_proc_flags;
+
+ /** Auto vibrato / tremolo / pannolo envelope retrigger flags.
+ Sequencers differ in the way how they handle envelopes restart.
+ Some continue the previous instrument envelope when a new
+ instrument does not define an envelope, others disable this
+ envelope instead. */
+ uint8_t env_retrig_flags;
+
+ /** Auto vibrato / tremolo / pannolo envelope randomize flags.
+ 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. */
+ uint8_t env_random_flags;
+
+ /** Auto vibrato sweep. */
+ uint16_t vibrato_sweep;
+
+ /** Auto vibrato depth. */
+ uint8_t vibrato_depth;
+
+ /** Auto vibrato rate (speed). */
+ uint8_t vibrato_rate;
+
+ /** Auto tremolo sweep. */
+ uint16_t tremolo_sweep;
+
+ /** Auto tremolo depth. */
+ uint8_t tremolo_depth;
+
+ /** Auto tremolo rate (speed). */
+ uint8_t tremolo_rate;
+
+ /** Auto pannolo sweep. */
+ uint16_t pannolo_sweep;
+
+ /** Auto panoolo depth. */
+ uint8_t pannolo_depth;
+
+ /** Auto pannolo rate (speed). */
+ uint8_t pannolo_rate;
+
+ /** 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 samples in those
+ chunks, which then won't get lost in that case. */
+ uint8_t **unknown_data;
+} AVSequencerSample;
+
+#endif /* AVSEQUENCER_SAMPLE_H */
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc