Here is a little utility for checking the read and write integrity of monaural 24-bit wav files under PureBasic.
You can use any monaural 24-bit wav file which has the old-fashioned wav header as the input file. I created a sine-wave file as my input file. This made it easy to verify that the output file was an exact replica of the data contained in the input file. The output file is a raw sound file with the extension .snd. There is no wav file header. I leave it to the reader to add one if he wants, or to add multichannel support. I use the program Goldwave to read the .snd file. The program reads the PCM data from the file into a buffer and then reads the data from the buffer and writes it back into the .snd file. It also reports the time this takes. You can also do multiple iterations for extended time testing by enabling the For/Next loop which is currently commented out. There are some hard-coded values for reading the wav file contents which is not the best way to do it; that's another project for the reader.
;CHECKS INTEGRITY OF 24-BIT READING AND WRITING ROUTINES
;UPDATED ON 3/5/12
Global format.WAVEFORMATEX: Global offset.l, sample.l
Global Dim sampleData.d(1)
filename$ = ".\24 bit test.wav"
result = ReadFile(1, filename$)
If result = 0
MessageRequester("Error", "Unable to open file " + fileName$)
sampleRate = ReadLong(1)
format\wBitsPerSample = ReadWord(1)
If format\wBitsPerSample <> 24
MessageRequester("Error", "Incorrect bit depth. Must be 24 bits.")
format\nBlockAlign = format\wBitsPerSample / 8
Repeat ;GO PAST HEADER
seek$ = LCase(Right(seek$ + Chr(ReadByte(1)), 4))
Until seek$ = "data"
subChunk2Size = ReadLong(1) ;SIZE OF AUDIO DATA IN BYTES
*soundBuffer = AllocateMemory(subChunk2Size)
bytes_read = ReadData(1, *soundbuffer, subChunk2Size)
CreateFile(1, ".\24 bit output.snd")
bufferEnd = (*soundBuffer - 0) + subChunk2Size
now = ElapsedMilliseconds()
For ct2 = 1 To 10
;THERE ARE TWO DIFFERENT WAYS TO READ 24-BIT SAMPLES FROM THE BUFFER. METHOD #1 IS FASTER.
*offset = *soundBuffer - 1 ;USE FOR METHOD #1
;*offset = *soundBuffer ;USE FOR METHOD #2
sample.l = PeekL(*offset) >> 8
; lsb.u = PeekU(*offset) ;USE UNSIGNED PUREBASIC TYPE "UNICODE"
; msb.b = PeekB(*offset + 2) ;THIS BYTE MUST BE SIGNED
; sample = msb << 16 | lsb
WriteData(1, @sample, 3)
*offset + format\nBlockAlign
Until *offset >= bufferEnd
PrintN(Str(ElapsedMilliseconds() - now))
PrintN(Chr(10) + "Press any key to exit.")
While Inkey() = "": Wend