Recent

Author Topic: There is a way to open a wav files in order to get the data structure?  (Read 960 times)

metallaro1980

  • New Member
  • *
  • Posts: 22
in order to elaborate these data?
thank you very much.

lucamar

  • Hero Member
  • *****
  • Posts: 2032
A WAV file is just that: a file. You can open it and read from it like for any other file: either with old-style file calls or with a stream.

Its structure is pretty well defined and yo can find it by gogling or (probably) in the MSDN: there is the RIFF header, the WAV header, the sample data, etc. It has varied very little from the days Windows 3.1 :)

I've attached a very old small (Turbo Pascal) program of mine to show you how it may be done, but note: 1) it's Turbo Pascal; 2) I implemented only what I needed; 3) It's old (late 1990s).

What are you trying to acomplish? Maybe there is some lib out there that would help you make it easier. Or, if you're in Windows, there are APIs to read/write from RIFF files and to treat with WAV files in particular.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

metallaro1980

  • New Member
  • *
  • Posts: 22
A WAV file is just that: a file. You can open it and read from it like for any other file: either with old-style file calls or with a stream.

Its structure is pretty well defined and yo can find it by gogling or (probably) in the MSDN: there is the RIFF header, the WAV header, the sample data, etc. It has varied very little from the days Windows 3.1 :)

I've attached a very old small (Turbo Pascal) program of mine to show you how it may be done, but note: 1) it's Turbo Pascal; 2) I implemented only what I needed; 3) It's old (late 1990s).

What are you trying to acomplish? Maybe there is some lib out there that would help you make it easier. Or, if you're in Windows, there are APIs to read/write from RIFF files and to treat with WAV files in particular.

I understand something about wav but i think for a 24 bits wav i need a 3 bytes for data structure for any channels..and how can convert to a floating number? this 3 bytes are in a logic order.... i think. how?

sash

  • Sr. Member
  • ****
  • Posts: 266
Try sndfile library. IIRC FPC even has a package.
Lazarus 2.0.2 FPC 3.0.4 x86_64-linux-gtk2 -- Ubuntu 19.04 XFCE

lucamar

  • Hero Member
  • *****
  • Posts: 2032
I understand something about wav but i think for a 24 bits wav i need a 3 bytes for data structure for any channels..and how can convert to a floating number? this 3 bytes are in a logic order.... i think. how?

Let's suposse a sample can be read fo the file as an array[0.2] of byte. You can easily convert it to a 32 bits integer (depending on its structure) and then just assign the integer to a floating point var. Something like:
Code: Pascal  [Select]
  1. {assume Sample is an array [0..2] of byte,
  2. in little-endian order, you read from the WAV file}
  3.   { Move Sample to a normal Integer}
  4.   AnInteger := Sample[0];
  5.   AnInteger := (AnInteger shl 8) + Sample[1];
  6.   AnInteger := (AnInteger shl 8) + Sample[2];
  7.   { And convert to floating point }
  8.   AFloat := AnInteger;
  9.  

Here is a good description of the WAV files: WAVE PCM soundfile format
« Last Edit: May 21, 2019, 01:49:19 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

winni

  • Sr. Member
  • ****
  • Posts: 340

Remember that the WAV format is nearly 30 years old and it was never planed to support more than 16 Bit. The early 90s were the 16Bit time. So the WAV format then supported 8 or 16 Bits and one or two Channels. That was enough to play some Bing! Zisshhhh! Booom! for the desktop and for Audio CDs.

The different 24 and 32 Bit enhacements in integer format or float came around the year 2000 and were *not* created by M$/IBM, the original "fathers". So there is no clear definition for these formats.

Here are some explanations about 24 and 32 Bit from the company XOn from the year 2003:


https://www.xon.de/reference/XOnMultimediaHTML/index.html?24bit_general.htm


It's not that easy as Lucamar thought.

How about to face an audio format from this millenium?

Winni

lucamar

  • Hero Member
  • *****
  • Posts: 2032
Hmmm ... The format itself (RIFF file) is extensible enough and, indeed, Microsoft has extended it at various times.

Here is another nice explanation of the standard, reasonably modern format: Audio File Format Specifications: WAV.

But yes, there are quite a lot of non-standard WAV files out there ... including some by Microsoft themselves :)

ETA: Here is one ref. from MS -
Demystifying the WAV Format
« Last Edit: May 21, 2019, 09:59:26 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.


engkin

  • Hero Member
  • *****
  • Posts: 2513
Probably you are looking for code to get you started. FPC has small code located in:
fpc\3.0.4\source\packages\fcl-sound\src 

Mainly fpwavreader.pas.

Also, try this thread. It has a sample by wp to generate a wav file.

wp

  • Hero Member
  • *****
  • Posts: 6235
I am attaching a demo which reads wav files and displayes the data values in a chart and in a grid. Everything needed to read the wav file is contained in unit wavread; it is pure Pascal, no external libs needed. It supports uncompressed data only, but is able to correctly read integer (8, 16, 24, 32, 64 bit) and float values (32, 64 bit); the 3-byte case (24 bit) mentioned above is included.
« Last Edit: May 23, 2019, 03:12:50 pm by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

metallaro1980

  • New Member
  • *
  • Posts: 22
Code: Pascal  [Select]
  1.   type
  2.   ar24bit = array of byte;
  3.  
  4.  
  5. function ToFloat (b1:byte;b2:byte;b3:byte):extended;
  6. var i1:int64;
  7. var retval,Q:extended;
  8. var ar : array[0..2] of byte;
  9. begin
  10.   ar[0] := b1;
  11.   ar[1] := b2;
  12.   ar[2] := b3;
  13.   i1 := 0;
  14.   move ( ar, i1, 3);
  15.   i1 := (i1 and $7fffff) - (i1 and $800000);
  16.   retval := i1 /8388608;
  17.   result := retval;
  18. end;
  19.  
  20. function ConvertToByte(fl:extended):ar24bit;
  21. var ret1,ret2,ret3,ret4:longint;
  22. var retf:double;
  23. var ar : ar24bit;
  24. var retf2 : double;
  25. var ar2 : array[0..2] of byte;
  26. begin
  27.   retf := fl * 8388608 ;
  28.   ret1 := round(retf);
  29.   if (ret1 and $80000000) <> 0 then
  30.   begin
  31.     ret1 := ret1 or $00800000;
  32.   end;
  33.  
  34.   setlength(ar,0);
  35.   setlength(ar,3);
  36.  
  37.   Move(ret1, ar2, 3);
  38.   ar[0] := ar2[0];
  39.   ar[1] := ar2[1];
  40.   ar[2] := ar2[2];
  41.   result := ar;
  42.  
  43. end;                          

now i am looking for a function that can detect peaks

jamie

  • Hero Member
  • *****
  • Posts: 1997
back in the hay day for 8 bit the center line is $80 or $7F and 16 bit and above the
center line is 0.

 as for a peak detection, you could use an ArcTan2 function found in the math unit or you could simple
sum the readings using ABS(Sample) or ABS(LastSample);

engkin

  • Hero Member
  • *****
  • Posts: 2513
now i am looking for a function that can detect peaks

I suggest you create a new post for this question, and to define the peaks you are looking for. I don't think any value that is bigger than its neighbors is what you want.