?
Solved

Translate from C to PAS (raw to wav)

Posted on 2000-02-15
12
Medium Priority
?
917 Views
Last Modified: 2011-09-20
Hello,
I want to translate this code from C to Delphi (transform a raw sound file in a wav sound file, 16000 / 16 bits)

Thanks,

Jean-Pol
=====================

#include <stdio.h>
#include <sys/stat.h>
#include <windows.h>


long chunksize=0x10;
struct
{
                WORD    wFormatTag;
                WORD    wChannels;
                DWORD   dwSamplesPerSec;
                DWORD   dwAvgBytesPerSec;
                WORD    wBlockAlign;
                        WORD      wBitsPerSample;
} fmt;
int Raw2Wav(const char *rawfn, const char *wavfn, long frequency)
{
      struct _stat sb;
      if(!_stat(rawfn, &sb))            // OK
      {
            long samplecount=sb.st_size/2;
            long riffsize=samplecount*2+0x24;
            long datasize=samplecount*2;
            FILE *raw=fopen(rawfn,"rb");
            if(!raw) return -2;
            FILE *wav=fopen(wavfn,"wb");
            if(!wav)
            {
                  fclose(raw); return -3;
            }
            fwrite("RIFF",1,4,wav);
            fwrite(&riffsize,4,1,wav);
            fwrite("WAVEfmt ",1,8,wav);
            fwrite(&chunksize,4,1,wav);
            fmt.wFormatTag=1;      // PCM
            fmt.wChannels=1;      // MONO
            fmt.dwSamplesPerSec=frequency*1;
            fmt.dwAvgBytesPerSec=frequency*1*2;      // PCM 16 bits
            fmt.wBlockAlign=2;
            fmt.wBitsPerSample=16;
            fwrite(&fmt,sizeof(fmt),1,wav);
            fwrite("data",1,4,wav);
            fwrite(&datasize,4,1,wav);
            short buff[1024];
            while(!feof(raw))
            {
                  int cnt=fread(buff,2,1024,raw);
                  if(cnt==0) break;
                  fwrite(buff,2,cnt,wav);
            }
            fclose(raw);
            fclose(wav);
      }
      else      // File not found?
      {
            return -1;
      }
      return 0;
}
/*
int main(int argc, char arcv[])
{
      int ret=Raw2Wav("d:\\data\\ear\\pcm\\cmh1_st0058","c:\\temp\\essai.wav",16000);
}
*/

==========================
0
Comment
Question by:jpdupont
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 

Expert Comment

by:brunohe
ID: 2522779
..and what's the problem?
0
 
LVL 1

Expert Comment

by:AttarSoftware
ID: 2522818
Similar to :

(This should help)

-----------------------------------

const
  chunkSize = $10 ;

type
  fmt = record
          wFormatTag       : word ;
          wChannels        : word ;
          dwSamplesPerSec  : longint ;
          dwAvgBytesPerSec : longint ;
          wBlockAlign      : word ;
          wBitsPerSample   : word ;
        end ;

function Raw2Wav( rawFn : string ; waveFn : string ; frequency : longint ) : longint ;
var
  sb : t_stat ; // WHAT IS THIS?
  sampleCount : longint ;
  riffSize : longint ;
  dataSize : longint ;
  raw : file ;
  wav : file ;
  buff : array [ 0 .. 1024 ] of short ;
  cnt : longint ;
begin
  if( not _stat( rawfn, &sb ) ) then // OK
  begin
    samplecount := sb.st_size / 2 ;
    riffsize := samplecount * 2 + $24 ;
    datasize := samplecount * 2 ;
    AssignFile( raw, rawfn ) ;
    {$i-}Reset( raw, 1 ) ;{$i+}
    if( ioResult <> 0 ) then
    begin
      result := -2 ;
      exit ;
    end ;
    AssignFile( wav, wavfn ) ;
    {$i-}Rewrite( wav, 1 ) ;{$i+}
    if( ioResult <> 0 ) then
    begin
      CloseFile( raw ) ;
      result := -3 ;
      exit ;
    end ;
    BlockWrite( wav, "RIFF", 4 ) ;
    BlockWrite( wav, riffSize, 4 ) ;
    BlockWrite( wav, "WAVEfmt", 8 ) ;
    BlockWrite( wav, chunkSize, 4 ) ;

    fmt.wFormatTag := 1 ; // PCM
    fmt.wChannels := 1 ; // MONO
    fmt.dwSamplesPerSec := frequency * 1 ;
    fmt.dwAvgBytesPerSec := frequency * 1 * 2 ; // PCM 16 bits
    fmt.wBlockAlign := 2 ;
    fmt.wBitsPerSample := 16 ;
    BlockWrite( wav, fmt, sizeof(fmt) ) ;
    BlockWrite( wav, 'data', 4 ) ;
    BlockWrite( wav, dataSize, 4 ) ;
    while( not EOF( raw ) )
    begin
      BlockRead( raw, buff, 1024 * sizeof( short ), cnt ) ;
      if( cnt = 0 ) then break ;
      BlockWrite( wav, buf, cnt * sizeof( short ) ) ;
    end ;
    CloseFile( raw ) ;
    CloseFile( wav ) ;
  end else // File not found?
  begin
    result := -1;
    exit ;
  end ;
  return 0;
end ;

Hope it does,

Good luck

Tim.
0
 
LVL 1

Expert Comment

by:AttarSoftware
ID: 2522827
PS:  I havent compiled it, so you might get a few errors, and BlockRead and BlockWrite may have their parameters the wrong way round, but as it is from memory, I can accept that...  Hope you can too ;O)

Tim.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:jpdupont
ID: 2522829
The problem is :

I'm not able to translate this C code to a .PAS code ? (I dont "speak" C or C++)

Could you do this for me ?

Thanks,

JP
0
 
LVL 6

Expert Comment

by:Jaymol
ID: 2522896
Tim (AttarSoftware) just did it for you!

John.
0
 

Author Comment

by:jpdupont
ID: 2522944
sb : t_stat ; // WHAT IS THIS?

Error when compiling here and after ...
0
 
LVL 1

Expert Comment

by:AttarSoftware
ID: 2523072
Ok, change the top 23 lines to:

function Raw2Wav( rawFn : string ; waveFn : string ; frequency : longint ) : longint ;
var
  sz : longint ; //CHANGED!
  sampleCount : longint ;
  riffSize : longint ;
  dataSize : longint ;
  raw : file ;
  wav : file ;
  buff : array [ 0 .. 1024 ] of short ;
  cnt : longint ;
begin
  AssignFile( raw, rawfn ) ;
  {$i-}Reset( raw, 1 ) ;{$i+}
  if( ioResult <> 0 ) then
  begin
    result := -2 ;
    exit ;
  end ;
  samplecount := FileSize( raw ) div 2 ;
  riffsize := samplecount * 2 + $24 ;
  datasize := samplecount * 2 ;

and get rid of:

  end else // File not found?
  begin
    result := -1;
    exit ;
  end ;

at the bottom...

Better?

Hope so ;O)

Tim.
0
 
LVL 1

Expert Comment

by:AttarSoftware
ID: 2523081
Heh, actually get rid of the

  sz : longint // CHANGED

line too :O)

  Almost hometime and Delphi from memory = confusion and too many defined variables ;O)

Good luck,

Tim.
0
 

Author Comment

by:jpdupont
ID: 2523792
Here the code (corrected ?). Compiles OK but the Wav file is not a correct wav file. (It seems to be 2x the size of the raw file). If you want give me a email address to send a test raw file.

JP

=============
type
  fmt = record
    wFormatTag: word;
    wChannels: word;
    dwSamplesPerSec: longint;
    dwAvgBytesPerSec: longint;
    wBlockAlign: word;
    wBitsPerSample: word;
  end;


function BabRaw2Wav(rawFn: string; waveFn: string; frequency: longint): longint;
var
  sampleCount: longint;
  riffSize: longint;
  dataSize: longint;
  chunkSize : longint;
  raw: file;
  wav: file;
  buff: array[0..1024] of short;
  cnt: longint;
  Afmt:fmt;
begin
  chunkSize := $10;
  AssignFile(raw, rawfn);
  AssignFile(wav, wavefn);
{$I-}Reset(raw, 1); {$I+}
  if (ioResult <> 0) then
  begin
    result := -2;
    exit;
  end;
  samplecount := FileSize(raw) div 2;
  riffsize := samplecount * 2 + $24;
  datasize := samplecount * 2;
{$I-}Rewrite(wav, 1); {$I+}
  if (ioResult <> 0) then
  begin
    CloseFile(raw);
    result := -3;
    exit;
  end;
  BlockWrite(wav, 'RIFF', 4);
  BlockWrite(wav, riffSize, 4);
  BlockWrite(wav, 'WAVEfmt', 8);
  BlockWrite(wav, chunkSize, 4);
  Afmt.wFormatTag := 1; // PCM
  Afmt.wChannels := 1; // MONO
  Afmt.dwSamplesPerSec := frequency * 1;
  Afmt.dwAvgBytesPerSec := frequency * 1 * 2; // PCM 16 bits
  Afmt.wBlockAlign := 2;
  Afmt.wBitsPerSample := 16;
  BlockWrite(wav, Afmt, sizeof(fmt));
  BlockWrite(wav, 'data', 4);
  BlockWrite(wav, dataSize, 4);
  while (not EOF(raw)) do
  begin
    BlockRead(raw, buff, 1024 * sizeof(short), cnt);
    if (cnt = 0) then break;
    BlockWrite(wav, buff, cnt * sizeof(short));
  end;
  CloseFile(raw);
  CloseFile(wav);
end;
0
 
LVL 1

Accepted Solution

by:
AttarSoftware earned 800 total points
ID: 2526219
Unfortunatly, I cannot recieve attatchments at work :O(

(Draconian virus-paranoid email policy)

  It is probably to do with the size of the data that it writes during the while loop...  How big are short integers in C?  I guess that Delphi ones are a different size...  try changing the array to an array of word (and the blockwrite to cnt * sizeof(word) and see if that helps...)  If not word, try byte (and cnt * sizeof(byte))

Good luck

Tim.
0
 

Author Comment

by:jpdupont
ID: 2526317
Hello,

All seems to be good now :

1/ BlockWrite(wav, 'WAVEfmt', 8);
must be BlockWrite(wav, 'WAVEfmt ', 8);
(with a space after 'fmt')

2/ Byte is the good value.

Thanks, Tim !

BTW,
I found good wav info on

http://webperso.alma-net.net/burel/sp/tech_000/tech0.htm 
(in french)
and

http://technology.niagarac.on.ca/courses/comp630/WavFileFormat.html

JP
0
 

Author Comment

by:jpdupont
ID: 2526323
Thanks !
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question