Filter SDK/avs2pcm
From Avisynth wiki
(Difference between revisions)
(first version - works only for SAMPLE_INT16 and mono) |
|||
Line 1: | Line 1: | ||
+ | avs2pcm reads a script and outputs raw audio. | ||
+ | |||
+ | Here's avs2pcm.cpp: | ||
+ | |||
#include <stdio.h> | #include <stdio.h> | ||
#include <Windows.h> | #include <Windows.h> | ||
Line 95: | Line 99: | ||
const __int64 start = 0; | const __int64 start = 0; | ||
const __int64 count = vi.num_audio_samples; | const __int64 count = vi.num_audio_samples; | ||
− | + | const int channels = vi.AudioChannels(); | |
− | + | ||
__int64 bytes = vi.BytesFromAudioSamples(count); | __int64 bytes = vi.BytesFromAudioSamples(count); | ||
+ | int BlockAlign = vi.AudioChannels() * vi.BytesPerAudioSample(); | ||
+ | |||
+ | unsigned char* samples = new unsigned char[BlockAlign*count]; | ||
+ | clip->GetAudio(samples, start, count, env); | ||
fwrite(samples, bytes, 1, out_fh); | fwrite(samples, bytes, 1, out_fh); | ||
Line 113: | Line 120: | ||
return 0; | return 0; | ||
} | } | ||
+ | |||
+ | Compile this file into an EXE named avs2pcm.exe. See [[Filter_SDK/Compiling_instructions|compiling instructions]]. Now open the command line and go to the folder where avs2pcm.exe and your script (called example.avs here) are located. Our script: | ||
+ | |||
+ | Tone(length=1, frequency=2, samplerate=48000, channels=1, type="square", level=1.0) # float | ||
+ | ConvertAudioTo16Bit() | ||
+ | |||
+ | Type the following on the command line (the name of the output clip can be arbitrary in our application): | ||
+ | |||
+ | avs2pcm.exe example.avs output.pcm | ||
+ | |||
+ | So the output file will contain five frames of YV12 data (640x480). You can import it in AviSynth using the plugin NicAudio: | ||
+ | |||
+ | v = Blankclip(1000) | ||
+ | a = RaWavSource("D:\AviSynth\Plugins\avs2pcm\test_16bit.pcm", 48000, 16, 1) # little-endian | ||
+ | Audiodub(v,a).ConvertAudioTo16Bit().GetChannels(1) | ||
+ | Audiograph(20) # Audiograph doesn't support 24/32bit nor multichannel | ||
+ | |||
+ | === Line by line breakdown === | ||
+ | |||
+ | Here's a line-by-line breakdown of avs2pcm.cpp: | ||
+ | |||
+ | x |
Revision as of 23:36, 21 February 2014
avs2pcm reads a script and outputs raw audio.
Here's avs2pcm.cpp:
#include <stdio.h> #include <Windows.h> #include "avisynth.h" #define MY_VERSION "Avs2PCM 0.01" const AVS_Linkage *AVS_linkage = 0; int __cdecl main(int argc, const char* argv[]) { const char* infile = NULL; const char* outfile = NULL; FILE* out_fh; if (!strcmp(argv[1], "-h")) { fprintf(stderr, MY_VERSION "\n" "Usage: avs2pcm in.avs out.pcm\n"); return 2; } else { infile = argv[1]; outfile = argv[2]; } try { char* sample_type; typedef IScriptEnvironment* (__stdcall *DLLFUNC)(int); IScriptEnvironment* env; HMODULE avsdll = LoadLibrary("avisynth.dll"); if (!avsdll) { fprintf(stderr, "failed to load avisynth.dll\n"); return 2; } DLLFUNC CreateEnv = (DLLFUNC)GetProcAddress(avsdll, "CreateScriptEnvironment"); if (!CreateEnv) { fprintf(stderr, "failed to load CreateScriptEnvironment()\n"); FreeLibrary(avsdll); return 1; } env = CreateEnv(AVISYNTH_INTERFACE_VERSION); AVS_linkage = env->GetAVSLinkage(); AVSValue arg(infile); AVSValue res = env->Invoke("Import", AVSValue(&arg, 1)); if (!res.IsClip()) { fprintf(stderr, "Error: '%s' didn't return a video clip.\n", infile); FreeLibrary(avsdll); return 1; } PClip clip = res.AsClip(); if (clip->GetVersion() < 5) { fprintf(stderr, "Error: too old version ('%d') of avisynth.dll loaded.\nplease install v2.60 or later.\n", clip->GetVersion()); return 1; } VideoInfo vi = clip->GetVideoInfo(); if (!vi.HasAudio()) { fprintf(stderr, "Error: '%s' video only clip.\n", infile); FreeLibrary(avsdll); return 1; } fprintf(stderr, " %s:\n", infile); fprintf(stderr, " %d Herz,\n", vi.audio_samples_per_second); fprintf(stderr, " %d channels,\n", vi.nchannels); fprintf(stderr, " %I64d audio samples,\n", vi.num_audio_samples); switch(vi.SampleType()) { case SAMPLE_INT8 : sample_type = "8 bit"; break; case SAMPLE_INT16 : sample_type = "16 bit"; break; case SAMPLE_INT24 : sample_type = "24 bit"; break; case SAMPLE_INT32 : case SAMPLE_FLOAT : sample_type = "32 bit"; break; default: sample_type = "unknown sample type"; break; } fprintf(stderr, " %s", sample_type); out_fh = fopen(outfile, "wb"); if (!out_fh) { fprintf(stderr, "fopen(\"%s\") failed", outfile); FreeLibrary(avsdll); return 1; } const __int64 start = 0; const __int64 count = vi.num_audio_samples; const int channels = vi.AudioChannels(); __int64 bytes = vi.BytesFromAudioSamples(count); int BlockAlign = vi.AudioChannels() * vi.BytesPerAudioSample(); unsigned char* samples = new unsigned char[BlockAlign*count]; clip->GetAudio(samples, start, count, env); fwrite(samples, bytes, 1, out_fh); delete[] samples; env->DeleteScriptEnvironment(); FreeLibrary(avsdll); AVS_linkage = 0; } catch(AvisynthError err) { fprintf(stderr, "\nAvisynth error:\n%s\n", err.msg); return 1; } fclose(out_fh); return 0; }
Compile this file into an EXE named avs2pcm.exe. See compiling instructions. Now open the command line and go to the folder where avs2pcm.exe and your script (called example.avs here) are located. Our script:
Tone(length=1, frequency=2, samplerate=48000, channels=1, type="square", level=1.0) # float ConvertAudioTo16Bit()
Type the following on the command line (the name of the output clip can be arbitrary in our application):
avs2pcm.exe example.avs output.pcm
So the output file will contain five frames of YV12 data (640x480). You can import it in AviSynth using the plugin NicAudio:
v = Blankclip(1000) a = RaWavSource("D:\AviSynth\Plugins\avs2pcm\test_16bit.pcm", 48000, 16, 1) # little-endian Audiodub(v,a).ConvertAudioTo16Bit().GetChannels(1) Audiograph(20) # Audiograph doesn't support 24/32bit nor multichannel
Line by line breakdown
Here's a line-by-line breakdown of avs2pcm.cpp:
x