Krueger092397
asked on
.wav files in Pascal
Is it possible to use .wav files in Pascal programming? If so, how do you access them?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
First of all sorry for the long delay...
Beneath I've included the format of .wav files for stereo/mono 8-bits samples.
I didn't have the format definitions for 16-bit waves but I guess it should
be quite the same as the format below ...
After this definition some words on how to program the stuff
-------------------------
The rData chunk in a WAV file is split up into several further chunks:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄ¿
³ rData ³
³ Byte Length ³
³ Offset Name (in bytes) Description ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄ´
³ 00h wID 4h Contains the characters "WAVE" ³
³ 04h Format 14h Contains data which specifies the format ³
³ Chunk of the Data in the Data Chunk ³
³ 18h WAVE Data ? Contains the WAV audio data ³
³ Chunk ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ Ä
³ The Format Chunk ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
The Format Chunk is split up into these fields:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄ¿
³ Format ³
³ Chunk Length ³
³ Offset Name (in bytes) Description ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄ´
³ 00h fId 4 Contains the characters "fmt" ³
³ 04h fLen 4 Length of data in the format chunk ³
³ 08h wFormatTag 2 * ³
³ 0Ah nChannels 2 Number of channels, 1=mono, 2=stereo ³
³ 0Ch nSamplesPerSec 2 Playback frequency ³
³ 0Eh nAvgBytesPerSec 2 ** ³
³ 10h nBlockAlign 2 *** ³
³ 12h FormatSpecific 2 Format specific data area ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÙ
* The wFormatTag specifies the wave format, eg 1 = Pulse Code Modulation
(or in plain english, regular 8 bit sampled uncompressed sound)
** Indicates the average number of bytes a second the data should be
transferred at = nChannels * nSamplesPerSec * (nBitsPerSample / 8)
*** Indicates the block alignment of the data in the data chunk. Software
needs to process a multiplt of nBlockAlign at a time.
nBlockAlign = nChannels * (nBitsPerSample / 8)
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ Ä
³ The Data Chunk ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
The Data Chunk is split up into these fields:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄ¿
³ Data ³
³ Chunk Length ³
³ Offset Name (in bytes) Description ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄ´
³ 00h dId 4 Contains the characters "data" ³
³ 02h dLen 4 Length of data in the dData field ³
³ 00h dData dLen The actual waveform data ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÙ
In mono 8-bit files each byte represents one sample. In stereo 8-bit files
two bytes are stored for each sample, the first byte is the left channel
value, the next is the right channel value.
-------------------------- ---
So far the description, it is quite self explanary.
The way you should program depends on your own wishes, you have the possibility
of polling and DMA-playback.
If you use the polling method you should set up the timer-rate equal to the
sample frequency and hook an routine on the interrupt that reads out the buffer
sends the read data to your soundcard and after that increases your buffer offset.
So the routine should look like ...
procedure Hooktimer;interrupt;
Read (BufferOffset) {1 byte for mono / 2 bytes for stereo}
Write (2SoundCard)
BufferOffset + 1 {or 2 for stereo}
end;
A fairly simple method, but it costs a lot of CPU overhead. I prefer the DMA method
which is set up as a double-buffer (if your samples >64K)
This method works as follow :
1. Setup a DMA buffer of max 64 K (x Kb)
2. Place DMA in Auto initialise mode
3. Fill the total buffer with the first y Kb of the sample
4. Tell the soundcard to play through DMA where the total size of
the sample data to be played will be a half of the allocated size of the DMA buffer
5. The soundcard will generate an irq when it has played the first half of the buffer
6. A procedure should manage this irq by doing the followin:
1. Tell the soundcard to play the second half through DMA
2. Fill the first half of the buffer with new sample data that comes
after the first y Kb you have placed in the beginning
7. At the end of the 2nd half of the buffer the soundcard will again generat
an irq. This one can be handled the same way as mentioned in 6. except that
you now tell the soundcard to start at the beginning of the buffer and that
you fill the 2nd half of the buffer.
If you use the above alghorithm you will be able to play samples of infinite
length which only uses 2 interrupts and a fillmem per 64Kb of sample data. As
you can see this is a quite an improvement compared to the polling method.
The only question for you still maybe how to program the soundcard you possess.
If you just search with a engine you can find some description on how to program
your soundcard.
I hope this basic alghorithms + the .wav format are enough to play your own wav
files in Pascal.
There is only one but... Those routines are primarly ment to use in a DOS
environment, if your using pascal under windows you shouldn't even try it
this way, your computer will surely hang. I am not a windows programmer,
but as far I know you can use the standard multi-media procedures provided by
pascal for windows. I guess that you can set up a buffer where you put your
data and tells the mm-function at which playback rate it should go through
that buffer and what the handle is of the mm-device. something like that ...
I should have made it in such way ! But who am I ... I am not Borland or
Microsoft.
Hmm, it is not a very nice lay-out ... if you want it more clearer you could always leave your email here
Beneath I've included the format of .wav files for stereo/mono 8-bits samples.
I didn't have the format definitions for 16-bit waves but I guess it should
be quite the same as the format below ...
After this definition some words on how to program the stuff
-------------------------
The rData chunk in a WAV file is split up into several further chunks:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ rData ³
³ Byte Length ³
³ Offset Name (in bytes) Description ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ 00h wID 4h Contains the characters "WAVE" ³
³ 04h Format 14h Contains data which specifies the format ³
³ Chunk of the Data in the Data Chunk ³
³ 18h WAVE Data ? Contains the WAV audio data ³
³ Chunk ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄ
³ The Format Chunk ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
The Format Chunk is split up into these fields:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ Format ³
³ Chunk Length ³
³ Offset Name (in bytes) Description ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ 00h fId 4 Contains the characters "fmt" ³
³ 04h fLen 4 Length of data in the format chunk ³
³ 08h wFormatTag 2 * ³
³ 0Ah nChannels 2 Number of channels, 1=mono, 2=stereo ³
³ 0Ch nSamplesPerSec 2 Playback frequency ³
³ 0Eh nAvgBytesPerSec 2 ** ³
³ 10h nBlockAlign 2 *** ³
³ 12h FormatSpecific 2 Format specific data area ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
* The wFormatTag specifies the wave format, eg 1 = Pulse Code Modulation
(or in plain english, regular 8 bit sampled uncompressed sound)
** Indicates the average number of bytes a second the data should be
transferred at = nChannels * nSamplesPerSec * (nBitsPerSample / 8)
*** Indicates the block alignment of the data in the data chunk. Software
needs to process a multiplt of nBlockAlign at a time.
nBlockAlign = nChannels * (nBitsPerSample / 8)
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ
³ The Data Chunk ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
The Data Chunk is split up into these fields:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ Data ³
³ Chunk Length ³
³ Offset Name (in bytes) Description ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ 00h dId 4 Contains the characters "data" ³
³ 02h dLen 4 Length of data in the dData field ³
³ 00h dData dLen The actual waveform data ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
In mono 8-bit files each byte represents one sample. In stereo 8-bit files
two bytes are stored for each sample, the first byte is the left channel
value, the next is the right channel value.
--------------------------
So far the description, it is quite self explanary.
The way you should program depends on your own wishes, you have the possibility
of polling and DMA-playback.
If you use the polling method you should set up the timer-rate equal to the
sample frequency and hook an routine on the interrupt that reads out the buffer
sends the read data to your soundcard and after that increases your buffer offset.
So the routine should look like ...
procedure Hooktimer;interrupt;
Read (BufferOffset) {1 byte for mono / 2 bytes for stereo}
Write (2SoundCard)
BufferOffset + 1 {or 2 for stereo}
end;
A fairly simple method, but it costs a lot of CPU overhead. I prefer the DMA method
which is set up as a double-buffer (if your samples >64K)
This method works as follow :
1. Setup a DMA buffer of max 64 K (x Kb)
2. Place DMA in Auto initialise mode
3. Fill the total buffer with the first y Kb of the sample
4. Tell the soundcard to play through DMA where the total size of
the sample data to be played will be a half of the allocated size of the DMA buffer
5. The soundcard will generate an irq when it has played the first half of the buffer
6. A procedure should manage this irq by doing the followin:
1. Tell the soundcard to play the second half through DMA
2. Fill the first half of the buffer with new sample data that comes
after the first y Kb you have placed in the beginning
7. At the end of the 2nd half of the buffer the soundcard will again generat
an irq. This one can be handled the same way as mentioned in 6. except that
you now tell the soundcard to start at the beginning of the buffer and that
you fill the 2nd half of the buffer.
If you use the above alghorithm you will be able to play samples of infinite
length which only uses 2 interrupts and a fillmem per 64Kb of sample data. As
you can see this is a quite an improvement compared to the polling method.
The only question for you still maybe how to program the soundcard you possess.
If you just search with a engine you can find some description on how to program
your soundcard.
I hope this basic alghorithms + the .wav format are enough to play your own wav
files in Pascal.
There is only one but... Those routines are primarly ment to use in a DOS
environment, if your using pascal under windows you shouldn't even try it
this way, your computer will surely hang. I am not a windows programmer,
but as far I know you can use the standard multi-media procedures provided by
pascal for windows. I guess that you can set up a buffer where you put your
data and tells the mm-function at which playback rate it should go through
that buffer and what the handle is of the mm-device. something like that ...
I should have made it in such way ! But who am I ... I am not Borland or
Microsoft.
Hmm, it is not a very nice lay-out ... if you want it more clearer you could always leave your email here
ASKER