Solved

Translate from C to PAS (raw to wav)

Posted on 2000-02-15
12
904 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
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
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 

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 200 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

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Path  to current project in Delphi. 2 79
Magic Software info 18 130
Need Help Delphi 2010 CheckBox1 Stored value in memo 13 66
update joined tables 2 45
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…

776 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