How to get started with an audio filter.
The best filters to take a look at is the [internal audio filters] of AviSynth. Mainly audio.cpp is interesting.
Basicly you override GetAudio(...) instead of GetFrame, and fill the buffer with data. A simple filter could look like this:
Filter creation - skip if no audio:
AVSValue __cdecl HalfVolume::Create(AVSValue args, void*, IScriptEnvironment* env) {
if (!args[0].AsClip()->GetVideoInfo().AudioChannels())
return args[0];
}
Constructor:
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 (from the CVS link above). What it does is automatic sample type conversion. Basicly 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 [here] and look at audio.cpp a bunch of more advanced stuff. A lot of technical details are also to be found in AviSynthTwoFiveAudio.
Back to FilterSDK.