1 Perl script
On the Peking University Chinese forum, a netizen asked how to play the PCM data from the end. I used to encounter 8 K sampled PCM data at work. At that time, I was not clear about the wav file format. The Perl module has an audio: WAV module that can write wav files, a Perl script is written:
use Audio::Wav;my $wav = new Audio::Wav;my $sample_rate = 8000;my $bits_sample = 16;my $details = { 'bits_sample' => $bits_sample, 'sample_rate' => $sample_rate, 'channels' => 1, };my $write = $wav -> write( 'testout.wav', $details );my $inputFile = "dout.txt";open (INFILE, "<$inputFile") or die "The file $inputFile "."could not be opened./n";my @pcm_data =
;close(INFILE);my $samp;foreach $samp(@pcm_data) {chomp($samp);$write -> write( $samp );}$write -> finish();
These scripts can convert PCM Data to WAV Files. Later, I saw the wav file format and thought it was very simple. This time I saw some netizens mention this problem, so I took the time to write a small program.
2 pcm2wav
Converting PCM Data to WAV Files only adds a file header. However, it takes time to use the interface for common users. I found a previously written html2txt project and modified it. It took me half a night and one noon to complete the pcm2wav program.
3. Implementation Principle
There is an article titled "Analysis of Wav file formats" written by Cao Jing on the Internet that has already introduced WAV file formats. Interested readers can refer to it. Wav files usually contain four segments: Riff, format segment, fact segment, and data segment. PCM data is placed in the data segment. As long as the format set for the format segment is consistent with the data segment, the playing program can correctly parse the data segment. The data in the following array is actually the smallest WAV file.
Static const unsigned char wav_template [] = {// riff wave chunk0x52, 0x49, 0x46, 0x46, // "riff" 0x30, 0x00, 0x00, 0x00, // The total length of the whole WAV file minus the number of bytes occupied by ID and size 0x57, 0x41, 0x56, 0x45, // "wave" // format chunk0x66, 0x6d, 0x74, 0x20, // "FMT" 0x10, 0x00, 0x00, 0x00, // block length 0x01, 0x00, // encoding method 0x01, 0x00, // number of audio channels 0x80, 0x3e, 0x00, 0x00, // the sampling frequency is 0x00, 0x7d, 0x00, 0x00, // required bytes per second = sampling frequency * block alignment bytes 0x02, 0x00, // Data Alignment bytes = number of each sample byte * number of channels 0x10, 0x00, // sample width // fact chunk0x66, 0x61, 0x63, 0x74, // "fact" 0x04, 0x00, 0x00, 0x00, // block length 0x00, 0xbe, 0x00, 0x00, // data chunk0x64, 0x61, 0x74, 0x61, // "data" 0x00, 0x00, 0x00, 0x00, // block length };
The Data Length of this wav file is 0. To add PCM Data, you only need to do the following:
- Add PCM data at the end of the data section;
- Modify the block length of the Data Segment and the total length of the riff segment;
- Set the PCM parameter of the format segment correctly.
The sample length may not be an integer multiple of 8. In this case, the wav file still requires the samples to be aligned in bytes. In a sample, the data is left aligned, and the right vacant space is filled with 0. Pcm2wav only considers the sample length as 16 bits.
If there are multiple channels, the wav file requires that the data of each channel of sample 1 be put first, and then the data of each channel of sample 2 be put, and so on. Because I have never met the need to process multi-channel data, pcm2wav only considers single-channel data.
4 Conclusion
You canHereDownload the pcm2wav program. If you want to convert individual files, you can use a program called wavecn. However, wavecn does not support big endian. I don't use PCM data very much now, but writing such a simple program is actually similar to playing a small game. Some steps are step-by-step, a few off-cards and a little joy of success.
5 postscript
According to user requirements, added single-channel, dual-channel selection, sample width, more sampling rate, and input sampling rate.