The best filters to take a look at if you are searching for a way to get
started with an audio filter is the
internal audio filters
of AviSynth. Mainly
audio.cpp
is interesting.
Basically you override GetAudio(...) instead of GetFrame, and fill the buffer with data. A simple filter could look like this:
AVSValue __cdecl HalfVolume::Create(AVSValue args, void*, IScriptEnvironment* env) { if (!args[0].AsClip()->GetVideoInfo().AudioChannels()) return args[0]; return new HalfVolume(args[0].AsClip()); }
HalfVolume::HalfVolume(PClip _child) : GenericVideoFilter(ConvertAudio::Create(_child, SAMPLE_INT16 | SAMPLE_FLOAT, SAMPLE_FLOAT)) { }
This is a bit tricky. It'll require you to include
ConvertAudio.cpp
.
What it does is automatic sample type conversion. Basically what it does is
that you tell that your filter supports SAMPLE_INT16 and SAMPLE_FLOAT, and
that it prefers SAMPLE_FLOAT. If the input isn't 16 bit or float, it'll be
converted to float.
void __stdcall HalfVolume::GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) { child->GetAudio(buf, start, count, env); int channels = vi.AudioChannels(); if (vi.SampleType() == SAMPLE_INT16) { short* samples = (short*)buf; for (int i=0; i< count; i++) { for(int j=0;j< channels;j++) { samples[i*channels+j] /= 2; } } } else if (vi.SampleType() == SAMPLE_FLOAT) { SFLOAT* samples = (SFLOAT*)buf; for (int i=0; i< count; i++) { for(int j=0;j< channels;j++) { samples[i*channels+j] /= 2.0f; } } } }
Implementation of a half volume filter. Very explicit, so it isn't going to
be the fastest possible, but it should serve the purpose. Furthermore have a look
discussion here
and look also at
audio.cpp
for a bunch of more advanced stuff. A lot of technical details are also to be
found in AviSynth Two-Five Audio.
$Date: 2007/07/04 00:12:07 $
Original version of this document at
http://www.avisynth.org/GettingStartedWithAudio