View difference between Paste ID: Xh5w9EcJ and TD3Sd8fP
SHOW: | | - or go back to the newest paste.
1
unit Wave;
2
3
interface
4
5
uses SysUtils, Types, Classes, math;
6
7
type
8
  TRIFFHeader = packed record
9
    ID : array[0..3] of Char;
10
    Length: DWORD;
11
    WaveID: array[0..3] of Char;
12
  end;
13
  TFormatHeader = packed record
14
    ID : array[0..3] of Char;
15
    Length : DWORD;
16
    FormatTag : WORD;
17
    Channels : WORD;
18
    SamplesPerSec : DWORD;
19
    AvgBytesPerSec: DWORD;
20
    BlockAlign : WORD;
21
    BitsPerSample : WORD;
22
  end;
23
  TDataHeader = packed record
24
    ID : array[0..3] of Char;
25
    Length: DWORD;
26
  end;
27
  TWaveHeader = packed record
28
    RIFF: TRIFFHeader;
29
    Format: TFormatHeader;
30-
  TWaveContent = Array of TWaveSample;
30+
31
  end;
32
  TWaveSample = packed record
33
    Left: Smallint;
34
    Right: Smallint;
35
  end;
36
  TWaveContent = packed Array of TWaveSample;
37
//  TWaveContent = Array of SmallInt;
38
39
function LoadWAVEFile(FileName: String): TWaveContent;
40
procedure FadeWAVE(var WaveContent: TWaveContent; MilliSeconds: SmallInt);
41
function CountQuietSamples(WaveContent: TWaveContent; ThresHold: SmallInt): Integer;
42
procedure SaveWAVEFile(WaveContent: TWaveContent; FileName: String);
43
44
implementation
45
46
function LoadWAVEFile(FileName: String): TWaveContent;
47
var
48
  WaveHeader: TWaveHeader;
49
  FStream: TFileStream;
50
  WaveLength: Integer;
51
begin
52
  try
53
    if FileExists(FileName) then begin
54
      FStream := TFileStream.Create(FileName,fmOpenRead);
55
      FStream.Read(WaveHeader,SizeOf(TWaveHeader)); // Den kompletten Header auslesen
56
      WaveLength := WaveHeader.Data.Length * 8 div (WaveHeader.Format.BitsPerSample
57
                    * WaveHeader.Format.Channels); // Länge des Arrays berechnen...
58
      SetLength(Result, WaveLength);
59
      FStream.Read(Result[0], WaveLength * 4);
60
      // Die Größe ist 4x so groß wie die Länge, weil 2 Channels * 2 Bytes / Sample
61
    end;
62
  finally
63
    FStream.Free
64
  end;
65-
    FStream.Write(WaveContent, 2048{WaveLength * 4});
65+
66
67
procedure SaveWAVEFile(WaveContent: TWaveContent; FileName: String);
68
var
69
  WaveHeader: TWaveHeader;
70
  FStream: TFileStream;
71
  WaveLength: Integer;
72
begin
73
  try
74
    FStream := TFileStream.Create(FileName, fmCreate);
75
    WaveLength := length(WaveContent);
76
77
    with WaveHeader do begin
78
      with RIFF do begin
79
        ID := 'RIFF';
80
        Length := 4 + WaveLength * 4 + SizeOf(TFormatHeader) + SizeOf(TDataHeader);
81
        WaveID := 'WAVE';
82
      end;
83
      with Format do begin
84-
      FStream.Read(Result, WaveLength * 4);
84+
85
        Length := SizeOf(TFormatHeader)-8;
86
        FormatTag := $0001;
87
        Channels := 2;
88
        SamplesPerSec := 44100;
89
        AvgBytesPerSec := 176400;
90-
end;
90+
91
        BitsPerSample := 16;
92
      end;
93
      with Data do begin
94
        ID := 'data';
95
        Length := WaveLength * 4;
96
      end;
97
    end;
98
//    WriteLn(WaveLength);
99
    FStream.Write(WaveHeader, SizeOf(TWaveHeader));
100
    FStream.Write(WaveContent[0], WaveLength * 4);
101
  finally
102
    FStream.Free;
103
  end;
104
end;
105
106
procedure FadeWAVE(var WaveContent: TWaveContent; MilliSeconds: SmallInt);
107
var
108
  Sample, Samples: Integer;
109
begin
110
  Samples := min(abs(Round(MilliSeconds * 44.1)),length(WaveContent)-1);
111
  // 1. Aus den Millisekunden wird die Anzahl der Samples gerechnet
112
  // 2. Die Maximale Dauer des Fades wird auf die Länge des Arrays gesetzt.
113
  if MilliSeconds > 0 then begin // Positiver Wert => FadeIn
114
    for Sample := 0 to Samples do begin
115
      WaveContent[Sample].Left  := Round(WaveContent[Sample].Left  * Sample / Samples);
116
      WaveContent[Sample].Right := Round(WaveContent[Sample].Right * Sample / Samples);
117
    end;
118
  end else begin // Negativer Wert => FadeOut
119
    for Sample := length(WaveContent) - Samples to length(WaveContent)- 1 do begin
120
      WaveContent[Sample].Left  := Round(WaveContent[Sample].Left * (length(WaveContent)
121
                                         - Sample) / Samples);
122
      WaveContent[Sample].Right := Round(WaveContent[Sample].Right * (length(WaveContent)
123
                                         - Sample) / Samples);
124
    end;
125
  end;
126
end;
127
128
end.