; // KillSilence Copyrigth 2006 by Andrej Stever ; // ; // This program is free software; you can redistribute it and/or modify ; // it under the terms of the GNU General Public License as published by ; // the free software Foundation; either version 2 of the License, or ; // (at your option) any later Version. ; // ; // This program 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 General Public License For more details. ; // ; // You should have received A copy of the GNU General Public License ; // along with This program; if not, write to the Free Software ; // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, Or visit ; // http://www.gnu.org/copyleft/gpl.html . Structure WAVEheader ckid.b[4]; /* chunk id 'RIFF' */ ckSize.l; /* chunk size */ wave_ckID.b[4]; /* wave chunk id 'WAVE' */ fmt_ckID.b[4]; /* format chunk id 'fmt ' */ fmt_ckSize.l; /* format chunk size */ formatTag.w; /* format tag currently pcm */ nChannels.w; /* number of channels */ nSamplesPerSec.l; /* sample rate in hz */ nAvgBytesPerSec.l; /* average bytes per second */ nBlockAlign.w; /* number of bytes per sample */ nBitsPerSample.w; /* number of bits in a sample */ data_ckID.b[4]; /* data chunk id 'data' */ data_ckSize.l; /* length of data chunk */ EndStructure #Source = 0 #Target = 1 thresh = 1 OpenConsole() ; // Parsing Args --------------------------------------------------- Dim argv.s(7) argc=0 Repeat If argc > 7 : Break : EndIf argv(argc) = ProgramParameter() If argv(argc) : argc + 1 : Else : Break :EndIf ForEver For i = 0 To argc If argv(i) ="-i" And i < argc -1 source.s = argv(i+1) ElseIf argv(i) ="-o" And i < argc -1 target.s = argv(i+1) ElseIf argv(i) ="-t" And i < argc -1 thresh.l = Val(argv(i+1)) ElseIf argv(i) ="-v" verbose.l = #True EndIf Next i PrintN("------------------------------------------------------------") PrintN("KillSilence 0.1 - a wave file silence cropper - 2006 by Inc.") PrintN("Detects and crops silence at the ") PrintN("beginning and at the end of a wave file") PrintN("------------------------------------------------------------") PrintN("") If (source="" Or target="") PrintN("Usage:") PrintN("-i [input.wav]") PrintN("-o [output.wav]") PrintN("-t [threshold 0-32768] ; default=10 ; 0=mega sensitive, 32768=leave it as it is") PrintN("-v verbose mode") End EndIf If thresh = 1 thresh = 10 EndIf If GetExtensionPart(target) = "wav" Or GetExtensionPart(target) = "WAV" Else PrintN("Wrong target suffix. Needs to be .wav") End EndIf ; // Parsing source wave header ----------------------------------------- If ReadFile(#Source,source) ReadData(@s_waveinfo.WAVEheader, SizeOf(WAVEheader)) Else PrintN("Could not open "+source) End EndIf If verbose PrintN("ChunkID : "+PeekS(@s_waveinfo\ckid,4)) PrintN("ChunkSize : "+Str(s_waveinfo\ckSize)) PrintN("WaveChunkID : "+PeekS(@s_waveinfo\wave_ckID,4)) PrintN("FormatChunkID : "+PeekS(@s_waveinfo\fmt_ckID,4)) PrintN("FormatChunkSize : "+Str(s_waveinfo\fmt_ckSize)) PrintN("FormatTag : "+Str(s_waveinfo\formatTag)) PrintN("ChannelCount : "+Str(s_waveinfo\nChannels)) PrintN("SamplesPerSec : "+Str(s_waveinfo\nSamplesPerSec)) PrintN("AvgBytesPerSec : "+Str(s_waveinfo\nAvgBytesPerSec)) PrintN("BlockAlign : "+Str(s_waveinfo\nBlockAlign)) PrintN("BitsPerSample : "+Str(s_waveinfo\nBitsPerSample)) PrintN("DataChunkID : "+PeekS(@s_waveinfo\data_ckID,4)) PrintN("LengthOfData : "+Str(s_waveinfo\data_ckSize)) PrintN("") EndIf ; // checking amplitude thresholds ----------------------------------------- Print("Now looking for audio start ") Repeat l_amp.w = ReadWord() r_amp.w = ReadWord() If l_amp > thresh Or l_amp < -thresh start = Loc() PrintN("---> filebyte "+Str(start)) Break ElseIf r_amp > thresh Or r_amp < -thresh start = Loc() PrintN("---> filebyte"+Str(start)) Break EndIf Until Eof(#Source) Print("Now looking for audio end ") FileSeek(Lof()-2) ; // Step back one WORD value from the very end of the file Repeat r_amp = ReadWord() FileSeek(Loc()-4) ; // Step back 2 WORDs l_amp = ReadWord() FileSeek(Loc()-4) ; // Step back 2 WORDs If l_amp > thresh Or l_amp < -thresh stop = Loc() PrintN("---> filebyte "+Str(stop)) Break ElseIf r_amp > thresh Or r_amp < -thresh stop = Loc() PrintN("---> filebyte "+Str(stop)) Break EndIf Until Loc() = SizeOf( WAVEheader) PrintN("") FileSeek(start) ; // Preparing target wave file ----------------------------------------- If CreateFile(#Target, target) Else PrintN("could not create target wave") End EndIf ; // copying the source waveheader to a target weaveheader strcuture CopyMemory(@s_waveinfo, @t_waveinfo.WAVEheader, SizeOf(WAVEheader)) ; // assigning target specific values to the target wave header t_waveinfo\data_ckSize = stop-start t_waveinfo\ckSize = t_waveinfo\data_ckSize+36 ; // writing the weaveheader to the target file UseFile(#Target) WriteData(@t_waveinfo,SizeOf(WAVEheader)) ; // copying the trimmed PCM data to the target file totalsize = t_waveinfo\data_ckSize bufferrest = t_waveinfo\data_ckSize % 1024 ; // Getting size of rest data which doesnt match 1MB buffer size buffercount = (t_waveinfo\data_ckSize-bufferrest) / 1024 ; // 1MB buffer Buffer = AllocateMemory(1024) PrintN("Copying trimmed PCM data ...") ; // 1MB buffer based data copy For i = 0 To buffercount UseFile(#Source) ReadData(Buffer, 1024) UseFile(#Target) WriteData(Buffer, 1024) Next i PrintN("finishing ...") ; // Word based data copy of the rest bytes (could also be enhanced) If bufferrest For i = 0 To bufferrest/2 ; // We do read WORDs so as the size of the UseFile(#Source) ; // Buffer is in bytes we do devide by 1word/2bytes amp.w = ReadWord() UseFile(#Target) WriteWord(amp.w) Next i EndIf CloseFile(#Target) CloseFile(#Source) PrintN("Ready.") End