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 2

Go to most recent revision | 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
-- Last update: 2008-08-23
8
-- 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
 --    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
-------------------------------------------------------------------------------
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
    variable Ret  : integer := 0;
104
    variable temp : natural := 0;
105
    variable ch   : character;
106
  begin
107
    for i in 0 to 3 loop
108
      read(WaveFileHandle, ch);
109
      temp := natural(character'pos(ch));
110
      Ret  := Ret + temp*2**(8*i);
111
    end loop;
112
    return Ret;
113
  end;
114
 
115
  function ReadWord(file WaveFileHandle : aFileHandle) return integer is
116
    variable Ret : integer := 0;
117
    variable ch  : character;
118
  begin
119
    for i in 0 to 1 loop
120
      read(WaveFileHandle, ch);
121
      Ret := Ret + character'pos(ch)*2**(8*i);
122
    end loop;
123
    return Ret;
124
  end;
125
 
126
  procedure OpenWaveFileRead(constant FileName   :     string;
127
                             file WaveFileHandle :     aFileHandle;
128
                             variable FileInfo   : out aWaveFileInfo) is
129
    variable ch         : character;
130
    variable Dummy      : integer;
131
    variable FileSize   : natural;
132
    variable FileStatus : file_open_status;
133
  begin
134
    file_open(FileStatus, WaveFileHandle, FileName, read_mode);
135
    assert(FileStatus = open_ok)
136
      report "Cannot open file " & FileName & "!" severity failure;
137
    assert(ReadString(WaveFileHandle, "RIFF"))
138
      report "The file " & FileName & " is not a wave file!" severity failure;
139
    FileSize := ReadDWord(WaveFileHandle) +8;            -- wrong dummy access!!!
140
    assert(ReadString(WaveFileHandle, "WAVE"))
141
      report "The file " & FileName & " is not a wave file!" severity failure;
142
    assert(ReadString(WaveFileHandle, "fmt "))
143
      report "The file " & FileName & " is not a wave file!" severity failure;
144
    assert(ReadDWord(WaveFileHandle) = 16)
145
      report "Uncommon header length, data will be corrupted!" severity failure;
146
    assert(ReadWord(WaveFileHandle) = 1)
147
      report "Cannot Handle any compressed file format" severity warning;
148
    FileInfo.Channels     := ReadWord(WaveFileHandle);
149
    FileInfo.SamplingRate := ReadDword(WaveFileHandle);
150
    Dummy                 := ReadDword(WaveFileHandle);  -- bytes/second
151
    Dummy                 := ReadWord(WaveFileHandle);   -- block align
152
    case ReadWord(WaveFileHandle) is
153
      when 8      => FileInfo.DataTyp := PCM8;
154
      when 16     => FileInfo.DataTyp := PCM16LE;
155
      when 32     => FileInfo.DataTyp := PCM32LE;
156
      when others =>
157
        report "Not Implemented!" severity failure;
158
    end case;
159
    assert(ReadString(WaveFileHandle, "data"))
160
      report "The file " & FileName & " is not a wave file!" severity failure;
161
    FileInfo.DataSize := ReadDword(WaveFileHandle);
162
  end;
163
 
164
  procedure ReadSample(file WaveFileHandle    :       aFileHandle;
165
                       variable Sample        : out   integer;
166
                       variable RemainingData : inout natural;
167
                       constant DataTyp       :       aWaveDataTyp) is
168
    variable Ret : integer := 0;
169
    variable ch  : character;
170
  begin
171
    if endfile(WaveFileHandle) = true then
172
      if RemainingData < 0 then
173
        report "Unexpected end of file!" severity error;
174
      else
175
        report "End of file reached!" severity note;
176
      end if;
177
    else
178
      case DataTyp is
179
        when PCM8 =>
180
          read(WaveFileHandle, ch);
181
          Ret           := character'pos(ch);
182
          RemainingData := RemainingData-1;
183
        when PCM16LE =>
184
          Ret           := ReadWord(WaveFileHandle);
185
          RemainingData := RemainingData-2;
186
        when PCM32LE =>
187
          Ret           := ReadDword(WaveFileHandle);
188
          RemainingData := RemainingData-4;
189
      end case;
190
    end if;
191
    Sample := Ret;
192
  end;
193
 
194
 
195
  procedure ReadSamples(file WaveFileHandle    :       aFileHandle;
196
                        variable Samples       : out   aIntArray;
197
                        variable RemainingData : inout natural;
198
                        constant Channels      :       natural;
199
                        constant DataTyp       :       aWaveDataTyp) is
200
    variable Ret : aIntArray(0 to Channels-1);
201
  begin
202
    for i in 0 to Channels-1 loop
203
      ReadSample(WaveFileHandle, Ret(i), RemainingData, DataTyp);
204
    end loop;
205
    Samples := Ret;
206
  end;
207
 
208
  procedure WriteString(file WaveFileHandle : aFileHandle;
209
                        constant Name       : string) is
210
  begin
211
    for i in Name'range loop
212
      write(WaveFileHandle, Name(i));
213
    end loop;
214
  end;
215
 
216
  procedure WriteChar(file WaveFileHandle : aFileHandle;
217
                      constant Value      : integer) is
218
    variable ch    : character;
219
    variable to_ch : integer;
220
  begin
221
    to_ch := Value;
222
    if to_ch < 0 then
223
      to_ch := 2**8 + to_ch;
224
    end if;
225
    ch := character'val(to_ch);
226
    write(WaveFileHandle, ch);
227
  end;
228
 
229
  procedure WriteDword(file WaveFileHandle : aFileHandle;
230
                       constant Value      : integer) is
231
    variable temp  : integer := 0;
232
    variable to_ch : integer := 0;
233
  begin
234
    temp := Value;
235
    for i in 0 to 3 loop
236
      to_ch := temp mod 2**8;
237
      WriteChar(WaveFileHandle, to_ch);
238
      temp  := (temp-to_ch)/2**8;
239
    end loop;
240
  end;
241
 
242
  procedure WriteWord(file WaveFileHandle : aFileHandle;
243
                      constant Value      : integer) is
244
    variable temp  : integer := 0;
245
    variable to_ch : integer := 0;
246
  begin
247
    temp := Value;
248
    for i in 0 to 1 loop
249
      to_ch := temp mod 2**8;
250
      WriteChar(WaveFileHandle, to_ch);
251
      temp  := (temp-to_ch)/2**8;
252
    end loop;
253
  end;
254
 
255
 
256
  procedure OpenWaveFileWrite(constant FileName   :       string;
257
                              file WaveFileHandle :       aFileHandle;
258
                              variable WaveFile   : inout aWaveFileInfo) is
259
    variable ch         : character;
260
    variable Size       : integer;
261
    variable FileStatus : file_open_status;
262
  begin
263
    file_open(FileStatus, WaveFileHandle, FileName, write_mode);
264
    assert(FileStatus = open_ok)
265
      report "Cannot open file " & FileName & "!" severity failure;
266
    WriteString(WaveFileHandle, "RIFF");                  -- 4
267
    Size := WaveFile.DataSize + 44 -8;
268
    WriteDword(WaveFileHandle, Size);   -- 8
269
    WriteString(WaveFileHandle, "WAVE");                  -- 12
270
    WriteString(WaveFileHandle, "fmt ");                  -- 16
271
    Size := 16;
272
    WriteDWord(WaveFileHandle, Size);   -- 20 size of format tag
273
    Size := 1;
274
    WriteWord(WaveFileHandle, Size);    -- 22 PCM stream
275
    WriteWord(WaveFileHandle, WaveFile.Channels);         -- 24
276
    WriteDWord(WaveFileHandle, WaveFile.SamplingRate);    -- 28
277
    case WaveFile.DataTyp is
278
      when PCM8    => Size := 8;
279
      when PCM16LE => Size := 16;
280
      when PCM32LE => Size := 32;
281
    end case;
282
    WriteDWord(WaveFileHandle, WaveFile.SamplingRate*WaveFile.Channels*Size/8);  -- bytes/second
283
    WriteWord(WaveFileHandle, WaveFile.Channels*Size/8);  -- block align
284
    WriteWord(WaveFileHandle, Size);
285
    WriteString(WaveFileHandle, "data");
286
    WriteDWord(WaveFileHandle, WaveFile.DataSize);
287
  end;
288
 
289
  procedure WriteSample(file WaveFileHandle    :       aFileHandle;
290
                        constant Sample        :       integer;
291
                        variable RemainingData : inout natural;
292
                        constant DataTyp       :       aWaveDataTyp) is
293
    variable ch : character;
294
  begin
295
    if RemainingData > 0 then
296
      case DataTyp is
297
        when PCM8 =>
298
          WriteChar(WaveFileHandle, Sample);
299
          RemainingData := RemainingData -1;
300
        when PCM16LE =>
301
          WriteWord(WaveFileHandle, Sample);
302
          RemainingData := RemainingData -2;
303
        when PCM32LE =>
304
          WriteDword(WaveFileHandle, Sample);
305
          RemainingData := RemainingData -4;
306
      end case;
307
    else
308
      report "Wave file is full, have you forgotten to set the data size for OpenWaveFileWrite!" severity error;
309
    end if;
310
  end;
311
 
312
  procedure WriteSamples(file WaveFileHandle    :       aFileHandle;
313
                         constant Samples       :       aIntArray;
314
                         variable RemainingData : inout natural;
315
                         constant Channels      :       natural;
316
                         constant DataTyp       :       aWaveDataTyp) is
317
  begin
318
    for i in 0 to Channels-1 loop
319
      WriteSample(WaveFileHandle, Samples(i), RemainingData, DataTyp);
320
    end loop;
321
  end;
322
 
323
end;
324
 

powered by: WebSVN 2.1.0

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