OpenCores
URL https://opencores.org/ocsvn/vhdl_wavefiles/vhdl_wavefiles/trunk

Subversion Repositories vhdl_wavefiles

[/] [vhdl_wavefiles/] [trunk/] [src/] [Wavefiles-p.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alex008
-------------------------------------------------------------------------------
2
-- Project    : VHDL WAVE files
3
-------------------------------------------------------------------------------
4
-- File       : Wavefiles-p.vhd
5
-- Author     : Alexander Lindert <alexander_lindert at gmx.at>
6
-- Created    : 2008-08-19
7 4 alex008
-- Last update: 2008-09-19
8 2 alex008
-- Platform   : 
9
-------------------------------------------------------------------------------
10
-- Description: This package can read or write VHDL signals from or to wave files.
11
-- There are no restriction for the numbers of channels and the sampling
12
-- frequences because Octave and Matlab can read them in every configuration.
13
-- Format used from this link:
14
-- http://www.lightlink.com/tjweber/StripWav/Canon.html
15
-------------------------------------------------------------------------------
16 4 alex008
--    GNU Lesser General Public License Version 3
17
--    =============================================
18
--    Copyright 2005 by Sun Microsystems, Inc.
19
--    901 San Antonio Road, Palo Alto, CA 94303, USA
20
--
21
--    This library is free software; you can redistribute it and/or
22
--    modify it under the terms of the GNU Lesser General Public
23
--    License version 3, as published by the Free Software Foundation.
24
--
25
--    This library is distributed in the hope that it will be useful,
26
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
27
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
28
--    Lesser General Public License for more details.
29
--
30
--    You should have received a copy of the GNU Lesser General Public
31
--    License along with this library; if not, write to the Free Software
32
--    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33
--    MA  02111-1307  USA
34 2 alex008
-------------------------------------------------------------------------------
35
-- Revisions  :
36
-- Date        Version  
37
-- 2008-08-19  1.0    
38
-------------------------------------------------------------------------------
39
 
40
package WaveFiles is
41
 
42
  type aFileHandle is file of character;
43
  type aWaveDataTyp is (PCM8, PCM16LE, PCM32LE);
44
  type aIntArray is array (natural range<>) of integer;
45
 
46
  type aWaveFileInfo is record
47
                          -- Handle       : aFileHandle;
48
                          Channels     : natural;
49
                          Datatyp      : aWaveDataTyp;
50
                          DataSize     : integer;
51
                          SamplingRate : natural;
52
                        end record;
53
 
54
  procedure OpenWaveFileRead(constant FileName   :     string;
55
                             file WaveFileHandle :     aFileHandle;
56
                             variable FileInfo   : out aWaveFileInfo);
57
 
58
 
59
  procedure ReadSample(file WaveFileHandle    :       aFileHandle;
60
                       variable Sample        : out   integer;
61
                       variable RemainingData : inout natural;
62
                       constant DataTyp       :       aWaveDataTyp);
63
 
64
  procedure ReadSamples(file WaveFileHandle    :       aFileHandle;
65
                        variable Samples       : out   aIntArray;
66
                        variable RemainingData : inout natural;
67
                        constant Channels      :       natural;
68
                        constant DataTyp       :       aWaveDataTyp);
69
 
70
  procedure OpenWaveFileWrite(constant FileName   :       string;
71
                              file WaveFileHandle :       aFileHandle;
72
                              variable WaveFile   : inout aWaveFileInfo);
73
 
74
  procedure WriteSample(file WaveFileHandle    :       aFileHandle;
75
                        constant Sample        :       integer;
76
                        variable RemainingData : inout natural;
77
                        constant DataTyp       :       aWaveDataTyp);
78
 
79
  procedure WriteSamples(file WaveFileHandle    :       aFileHandle;
80
                         constant Samples       :       aIntArray;
81
                         variable RemainingData : inout natural;
82
                         constant Channels      :       natural;
83
                         constant DataTyp       :       aWaveDataTyp);
84
end;
85
 
86
package body WaveFiles is
87
 
88
  function ReadString(file WaveFileHandle : aFileHandle;
89
                      constant Name       : string) return boolean is
90
    variable Ret : boolean := true;
91
    variable ch  : character;
92
  begin
93
    for i in Name'range loop
94
      read(WaveFileHandle, ch);
95
      if ch /= Name(i) then
96
        Ret := false;
97
      end if;
98
    end loop;
99
    return Ret;
100
  end;
101
 
102
  function ReadDword(file WaveFileHandle : aFileHandle) return integer is
103 4 alex008
    variable Ret : integer := 0;
104
    variable ch  : character;
105 2 alex008
  begin
106
    for i in 0 to 3 loop
107
      read(WaveFileHandle, ch);
108 4 alex008
      Ret := Ret + character'pos(ch)*2**(8*i);
109 2 alex008
    end loop;
110
    return Ret;
111
  end;
112
 
113
  function ReadWord(file WaveFileHandle : aFileHandle) return integer is
114
    variable Ret : integer := 0;
115
    variable ch  : character;
116
  begin
117
    for i in 0 to 1 loop
118
      read(WaveFileHandle, ch);
119
      Ret := Ret + character'pos(ch)*2**(8*i);
120
    end loop;
121
    return Ret;
122
  end;
123
 
124
  procedure OpenWaveFileRead(constant FileName   :     string;
125
                             file WaveFileHandle :     aFileHandle;
126
                             variable FileInfo   : out aWaveFileInfo) is
127
    variable ch         : character;
128
    variable Dummy      : integer;
129
    variable FileSize   : natural;
130
    variable FileStatus : file_open_status;
131
  begin
132
    file_open(FileStatus, WaveFileHandle, FileName, read_mode);
133
    assert(FileStatus = open_ok)
134
      report "Cannot open file " & FileName & "!" severity failure;
135
    assert(ReadString(WaveFileHandle, "RIFF"))
136
      report "The file " & FileName & " is not a wave file!" severity failure;
137
    FileSize := ReadDWord(WaveFileHandle) +8;            -- wrong dummy access!!!
138
    assert(ReadString(WaveFileHandle, "WAVE"))
139
      report "The file " & FileName & " is not a wave file!" severity failure;
140
    assert(ReadString(WaveFileHandle, "fmt "))
141
      report "The file " & FileName & " is not a wave file!" severity failure;
142
    assert(ReadDWord(WaveFileHandle) = 16)
143
      report "Uncommon header length, data will be corrupted!" severity failure;
144
    assert(ReadWord(WaveFileHandle) = 1)
145
      report "Cannot Handle any compressed file format" severity warning;
146
    FileInfo.Channels     := ReadWord(WaveFileHandle);
147
    FileInfo.SamplingRate := ReadDword(WaveFileHandle);
148
    Dummy                 := ReadDword(WaveFileHandle);  -- bytes/second
149
    Dummy                 := ReadWord(WaveFileHandle);   -- block align
150
    case ReadWord(WaveFileHandle) is
151
      when 8      => FileInfo.DataTyp := PCM8;
152
      when 16     => FileInfo.DataTyp := PCM16LE;
153
      when 32     => FileInfo.DataTyp := PCM32LE;
154
      when others =>
155
        report "Not Implemented!" severity failure;
156
    end case;
157
    assert(ReadString(WaveFileHandle, "data"))
158
      report "The file " & FileName & " is not a wave file!" severity failure;
159
    FileInfo.DataSize := ReadDword(WaveFileHandle);
160
  end;
161
 
162 4 alex008
 
163
  function ReadSignedDword(file WaveFileHandle : aFileHandle) return integer is
164
    variable Ret : integer := 0;
165
    variable ch  : character;
166
  begin
167
    for i in 0 to 3 loop
168
      read(WaveFileHandle, ch);
169
      Ret := Ret + character'pos(ch)*2**(8*i);
170
    end loop;
171
    return Ret;
172
  end;
173
 
174
  function ReadSignedWord(file WaveFileHandle : aFileHandle) return integer is
175
    variable Ret : integer := 0;
176
    variable ch  : character;
177
  begin
178
    for i in 0 to 1 loop
179
      read(WaveFileHandle, ch);
180
 
181
      Ret := Ret + character'pos(ch)*2**(8*i);
182
    end loop;
183
    if Ret >= 2**15 then
184
      Ret := Ret - 2**16;
185
    end if;
186
    return Ret;
187
  end;
188
 
189
  function ReadSignedByte(file WaveFileHandle : aFileHandle) return integer is
190
    variable Ret : integer := 0;
191
    variable ch  : character;
192
  begin
193
    read(WaveFileHandle, ch);
194
    Ret := character'pos(ch);
195
    if Ret >= 2**7 then
196
      Ret := Ret - 2**8;
197
    end if;
198
    return Ret;
199
  end;
200
 
201 2 alex008
  procedure ReadSample(file WaveFileHandle    :       aFileHandle;
202
                       variable Sample        : out   integer;
203
                       variable RemainingData : inout natural;
204
                       constant DataTyp       :       aWaveDataTyp) is
205
    variable Ret : integer := 0;
206
    variable ch  : character;
207
  begin
208
    if endfile(WaveFileHandle) = true then
209
      if RemainingData < 0 then
210
        report "Unexpected end of file!" severity error;
211
      else
212
        report "End of file reached!" severity note;
213
      end if;
214
    else
215
      case DataTyp is
216
        when PCM8 =>
217 4 alex008
          Ret           := ReadSignedByte(WaveFileHandle);
218 2 alex008
          RemainingData := RemainingData-1;
219
        when PCM16LE =>
220 4 alex008
          Ret           := ReadSignedWord(WaveFileHandle);
221 2 alex008
          RemainingData := RemainingData-2;
222
        when PCM32LE =>
223 4 alex008
          Ret           := ReadSignedDword(WaveFileHandle);
224 2 alex008
          RemainingData := RemainingData-4;
225
      end case;
226
    end if;
227
    Sample := Ret;
228
  end;
229
 
230
 
231
  procedure ReadSamples(file WaveFileHandle    :       aFileHandle;
232
                        variable Samples       : out   aIntArray;
233
                        variable RemainingData : inout natural;
234
                        constant Channels      :       natural;
235
                        constant DataTyp       :       aWaveDataTyp) is
236
    variable Ret : aIntArray(0 to Channels-1);
237
  begin
238
    for i in 0 to Channels-1 loop
239
      ReadSample(WaveFileHandle, Ret(i), RemainingData, DataTyp);
240
    end loop;
241
    Samples := Ret;
242
  end;
243
 
244
  procedure WriteString(file WaveFileHandle : aFileHandle;
245
                        constant Name       : string) is
246
  begin
247
    for i in Name'range loop
248
      write(WaveFileHandle, Name(i));
249
    end loop;
250
  end;
251
 
252
  procedure WriteChar(file WaveFileHandle : aFileHandle;
253
                      constant Value      : integer) is
254
    variable ch    : character;
255
    variable to_ch : integer;
256
  begin
257
    to_ch := Value;
258
    if to_ch < 0 then
259
      to_ch := 2**8 + to_ch;
260
    end if;
261
    ch := character'val(to_ch);
262
    write(WaveFileHandle, ch);
263
  end;
264
 
265
  procedure WriteDword(file WaveFileHandle : aFileHandle;
266
                       constant Value      : integer) is
267
    variable temp  : integer := 0;
268
    variable to_ch : integer := 0;
269
  begin
270
    temp := Value;
271
    for i in 0 to 3 loop
272
      to_ch := temp mod 2**8;
273
      WriteChar(WaveFileHandle, to_ch);
274
      temp  := (temp-to_ch)/2**8;
275
    end loop;
276
  end;
277
 
278
  procedure WriteWord(file WaveFileHandle : aFileHandle;
279
                      constant Value      : integer) is
280
    variable temp  : integer := 0;
281
    variable to_ch : integer := 0;
282
  begin
283
    temp := Value;
284
    for i in 0 to 1 loop
285
      to_ch := temp mod 2**8;
286
      WriteChar(WaveFileHandle, to_ch);
287
      temp  := (temp-to_ch)/2**8;
288
    end loop;
289
  end;
290
 
291
 
292
  procedure OpenWaveFileWrite(constant FileName   :       string;
293
                              file WaveFileHandle :       aFileHandle;
294
                              variable WaveFile   : inout aWaveFileInfo) is
295
    variable ch         : character;
296
    variable Size       : integer;
297
    variable FileStatus : file_open_status;
298
  begin
299
    file_open(FileStatus, WaveFileHandle, FileName, write_mode);
300
    assert(FileStatus = open_ok)
301
      report "Cannot open file " & FileName & "!" severity failure;
302
    WriteString(WaveFileHandle, "RIFF");                  -- 4
303
    Size := WaveFile.DataSize + 44 -8;
304
    WriteDword(WaveFileHandle, Size);   -- 8
305
    WriteString(WaveFileHandle, "WAVE");                  -- 12
306
    WriteString(WaveFileHandle, "fmt ");                  -- 16
307
    Size := 16;
308
    WriteDWord(WaveFileHandle, Size);   -- 20 size of format tag
309
    Size := 1;
310
    WriteWord(WaveFileHandle, Size);    -- 22 PCM stream
311
    WriteWord(WaveFileHandle, WaveFile.Channels);         -- 24
312
    WriteDWord(WaveFileHandle, WaveFile.SamplingRate);    -- 28
313
    case WaveFile.DataTyp is
314
      when PCM8    => Size := 8;
315
      when PCM16LE => Size := 16;
316
      when PCM32LE => Size := 32;
317
    end case;
318
    WriteDWord(WaveFileHandle, WaveFile.SamplingRate*WaveFile.Channels*Size/8);  -- bytes/second
319
    WriteWord(WaveFileHandle, WaveFile.Channels*Size/8);  -- block align
320
    WriteWord(WaveFileHandle, Size);
321
    WriteString(WaveFileHandle, "data");
322
    WriteDWord(WaveFileHandle, WaveFile.DataSize);
323
  end;
324
 
325
  procedure WriteSample(file WaveFileHandle    :       aFileHandle;
326
                        constant Sample        :       integer;
327
                        variable RemainingData : inout natural;
328
                        constant DataTyp       :       aWaveDataTyp) is
329
    variable ch : character;
330
  begin
331
    if RemainingData > 0 then
332
      case DataTyp is
333
        when PCM8 =>
334
          WriteChar(WaveFileHandle, Sample);
335
          RemainingData := RemainingData -1;
336
        when PCM16LE =>
337
          WriteWord(WaveFileHandle, Sample);
338
          RemainingData := RemainingData -2;
339
        when PCM32LE =>
340
          WriteDword(WaveFileHandle, Sample);
341
          RemainingData := RemainingData -4;
342
      end case;
343
    else
344
      report "Wave file is full, have you forgotten to set the data size for OpenWaveFileWrite!" severity error;
345
    end if;
346
  end;
347
 
348
  procedure WriteSamples(file WaveFileHandle    :       aFileHandle;
349
                         constant Samples       :       aIntArray;
350
                         variable RemainingData : inout natural;
351
                         constant Channels      :       natural;
352
                         constant DataTyp       :       aWaveDataTyp) is
353
  begin
354
    for i in 0 to Channels-1 loop
355
      WriteSample(WaveFileHandle, Samples(i), RemainingData, DataTyp);
356
    end loop;
357
  end;
358
 
359
end;
360
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.