This project provides VHDL packages for reading and writing uncompressed audio data in simulation.
WAV is a file format for storing audio data that’s widely used on Windows-based systems and by audio recording devices or editing software like the Adobe suite. Despite the emergence of more efficient audio codec algorithms, WAV remains a popular format for storing uncompressed, lossless audio data because of its simplicity and cross-platform support.
You can also use this method to test other kinds of signal processing modules, not only audio data. That’s because you can store any waveform in a WAV file, and these packages will help you work with them.
The downloadable ZIP contains WAV file samples and a quick start run script for the Questa/ModelSim VHDL simulator. The demo testbench reads a mono and a stereo WAV file and renders the audio signals as analog literals in the simulator’s waveform viewer. Finally, it writes the audio samples to new WAV files.
👇 Refer to the user manual for a description of how to use these VHDL packages.
Click here to download the WAV file RW packages – User Manual.pdf:
This project is also available in the VHDLwhiz Membership.
The difference is that when you purchase this product, you get immediate access to the downloadable Zip file, while you can only join the membership at certain times every year.
Furthermore, the membership charges a monthly subscription fee, while this product is a one-time purchase.
The code listing below shows the declarative region of the file reader package.
package wav_reader_pkg is type wav_reader is protected -- Open the wave file for reading -- -- @param filename The path to the input file -- procedure open_file(filename : string); -- Close the wave file if open procedure close_file; -- Check if the file has been opened for reading -- -- @return true if the file is open -- impure function is_open return boolean; -- Check if more data is available for reading from the file impure function is_empty return boolean; -- Code identifying the encoding of each sample channel -- 1 = Pulse-code modulation (PCM) -- 2 = Adaptive differential pulse-code modulation (ADPCM) -- 3 = IEEE floating-point number -- Etc. impure function get_audio_format return integer; -- The number of audio channels (mono = 1, stereo = 2) impure function get_num_channels return integer; -- The sampling rate in Hz impure function get_sample_rate return integer; -- Bits per sample, per channel impure function get_bits_per_sample return integer; -- The total number of samples in this file (sample sets, not channels) impure function get_total_samples return integer; -- The number of unread samples since opening this file impure function get_unread_samples return integer; -- Print the wave file header and other information procedure print_metainfo; -- Read audio sample (mono version) procedure read_sample(signal sample : out std_logic_vector); -- Read audio sample (stereo version) procedure read_sample(signal sample_l, sample_r : out std_logic_vector); end protected; end package;
The code listing below shows the declarative region of the file writer package.
package wav_writer_pkg is type wav_writer is protected -- Open the wave file for writing -- -- In addition to the filename, you need to supply information that goes into -- the header of the output wave file. If you are writing back samples that -- initially came from the wav_reader_pkg package, you can access those data -- from the reader's getter functions: get_audio_format, get_num_channels, -- get_sample_rate, get_bits_per_sample, get_total_samples, and get_unread_samples. -- -- @param filename The path to the input file -- @param audio_format Numeric value identifying the encoding of a sample channel -- @param num_channels Mono = 1, stereo = 2 -- @param sample_rate The sampling rate in Hz -- @param bits_per_sample Bits per sample, per channel (must be a multiple of 8) -- @param total_samples The exact number of samples you intend to write to this file -- procedure open_file( filename : string; audio_format : integer; num_channels : integer; sample_rate : integer; bits_per_sample : integer; total_samples : integer); -- Close the wave file if open -- -- You must call this procedure after calling write_sample() -- total_samples number of times. -- procedure close_file; -- Check if the file has been opened for writing -- -- @return true if the file is open -- impure function is_open return boolean; -- The number of samples left to write based on total_samples impure function get_samples_left_to_write return integer; -- Write one audio sample (mono version) procedure write_sample(constant sample : in std_logic_vector); -- Write one audio sample set (stereo version) procedure write_sample(constant sample_l, sample_r : in std_logic_vector); end protected; end package;
Copyright (c) 2022 Jonas Julian Jensen
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.