Google Answers Logo
View Question
 
Q: Visual Basic PCM Wav File Writing Source Code ( Answered 3 out of 5 stars,   6 Comments )
Question  
Subject: Visual Basic PCM Wav File Writing Source Code
Category: Computers > Programming
Asked by: rexrhino-ga
List Price: $15.00
Posted: 14 May 2002 09:17 PDT
Expires: 21 May 2002 09:17 PDT
Question ID: 16158
I am looking for Visual Basic Source Code that allows me to take an
array of audio sample data, and write it as a canonacal PCM WAV file
to disk. I need to be able to write 44.1 KHZ 16 bit stereo files.

Request for Question Clarification by blader-ga on 14 May 2002 11:47 PDT
Dear rexrhino:

Could you clarify your question for us by telling us what format the
source audio data is in?

Best Regards,
blader-ga

Clarification of Question by rexrhino-ga on 14 May 2002 13:25 PDT
The source audio is stored as an array of 16 bit integers, with
alternating left and right channels. The closest file format one could
compare it to would be "raw" file format. However, I would be using
the code to write an audio data generated algorithmicly by a program,
not to convert a "raw" file type to wav file. I am simply looking for
source code to write the wav file to disk.
Answer  
Subject: Re: Visual Basic PCM Wav File Writing Source Code
Answered By: philip_lynx-ga on 16 May 2002 02:02 PDT
Rated:3 out of 5 stars
 
Hi Rexrhino,

I am including C code that generates a .wav file with the following
properties:
test.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16
bit, stereo 44100 Hz.

Sorry this is no Visual Basic, but I hope it is readable, albeit
compact. The generated file contains a 450 Hz sine wave on the left
channel and a 452 Hz sine wave on the right channel, so you should
have a nice effect if all works. If my code is obscure or you have
questions of any kind, please do not hesitate to ask for
clarification.

As a reference (in case you want to let the code run locally) here the
first few lines of its output:
0000000  82  73  70  70 192 234  26   0  87  65  86  69 102 109 116 
32
          R   I   F   F   @   j sub nul   W   A   V   E   f   m   t 
sp

0000016  16   0   0   0   1   0   2   0  68 172   0   0  16 177   2  
0
        dle nul nul nul soh nul stx nul   D   , nul nul dle   1 stx
nul

0000032   4   0  16   0 100  97 116  97 160 234  26   0   0   0   0  
0
        eot nul dle nul   d   a   t   a  sp   j sub nul nul nul nul
nul

0000048  51   8  60   8  94  16 112  16 119  24 147  24 119  32 155 
32
          3  bs   <  bs   ^ dle   p dle   w can dc3 can   w  sp esc 
sp

The generated file is 1764040 bytes long, for ten seconds of audio.
Compile and ling agsint the math library (because of the sine
function), e.g.
with 'make LDLIBS+=-lm file.c'

#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

#define SECONDS 10 /* produce 10 seconds of noise */
#define PI 3.14159265358979

int put_little_short(char *t, unsigned int value)
{
    *(unsigned char *)(t++)=value&255;
    *(unsigned char *)(t)=(value/256)&255;
    return 2;
}
int put_little_long(char *t, unsigned int value)
{
    *(unsigned char *)(t++)=value&255;
    *(unsigned char *)(t++)=(value/256)&255;
    *(unsigned char *)(t++)=(value/(256*256))&255;
    *(unsigned char *)(t)=(value/(256*256*256))&255;
    return 4;
}

/* returns the number of bytes written. skips two bytes after
 * each write */
int fill_data(char *start, int frequency, int seconds)
{
    int i, len=0;
    int value;
    for(i=0; i<seconds*44100; i++) {
        value=32767.0 *
sin(2.0*PI*((double)(i))*(double)(frequency)/44100.0);
        put_little_short(start, value);
        start += 4;
        len+=2;
    }
    return len;
}

int main(void)
{
    char *buffer=malloc(SECONDS*44100*4+1000);
    char *t=buffer;
    int len;
    int fd;

    *t++='R'; *t++='I'; *t++='F'; *t++='F';
    t+=4; /* total length will be put in later */
    *t++='W'; *t++='A'; *t++='V'; *t++='E';

    /* format chunk, 8 bytes header and 16 bytes payload */
    *t++='f'; *t++='m'; *t++='t'; *t++=' ';
    t+=put_little_long(t,16); /* I know the length  of the fmt_ chunk
*/
    t+=put_little_short(t,1); /* chunk type is always one */
    t+=put_little_short(t,2); /* two channels */
    t+=put_little_long(t,44100); /* samples per second */
    t+=put_little_long(t,44100*2*2); /* bytes per second */
    t+=put_little_short(t,4); /* bytes pro sample (all channels) */
    t+=put_little_short(t,16); /* bits per sample */

    /* data chunk, 8 bytes header and XXX bytes payload */
    *t++='d'; *t++='a'; *t++='t'; *t++='a';

    len=fill_data(t+4,450,SECONDS); /* left channel, 450Hz sine */
    len+=fill_data(t+6,452,SECONDS); /* right channel, 452Hz sine */
    put_little_long(t,len);
    put_little_long(buffer+4,len+8+16+8);
    fd=open("test.wav", O_RDWR|O_CREAT, 0644);
    write(fd,buffer,len+8+16+8+8);
    close(fd);
    return 0;
}

I hope this solves your problem. All the best with your sounds :-)

--Philip

Clarification of Answer by philip_lynx-ga on 31 May 2002 06:11 PDT
Hi Rexrhino,
did you get things to work?
rexrhino-ga rated this answer:3 out of 5 stars
My question was addressed quickly, and the researcher sought
clarification before answering my question. I wasn't disapointed that
the answer wasn't exact, because it was a difficult thing to ask, and
the researcher made a serious effort. I could not give it 4 or 5
stars, however, because the question was really answered.

Comments  
Subject: Re: Visual Basic PCM Wav File Writing Source Code
From: tobyirc-ga on 14 May 2002 13:34 PDT
 
I tell ya what, get winamp 2.8 or other with DiskWrite plugin, you can
specify the wav file and those exact specifications... That is a
way... Also, I'm under 18 so i can't sign up, why can't my parent's
consent??? COME ON!!
Subject: Re: Visual Basic PCM Wav File Writing Source Code
From: rexrhino-ga on 14 May 2002 14:46 PDT
 
to tobyirc-ga:

There are many application that can convert a "raw" audio file to a
wav file, but I need to do it as part of a program I am writing, so I
cannot rely on another app to do it.

Thanks tho!
RexRhino
Subject: Re: Visual Basic PCM Wav File Writing Source Code
From: samrolken-ga on 14 May 2002 19:52 PDT
 
Would you be okay with a good description of the algorithm, and
examples in two other languages than VB? Any programmer worth the
title should be able to "translate" the code from languages like C++
or PASCAL into VB...
Subject: Re: Visual Basic PCM Wav File Writing Source Code
From: browolf-ga on 15 May 2002 02:21 PDT
 
this might help:
http://www.vbsquare.com/graphics/tip451.html

"This is a very simple yet affective example, this example shows you
how to record then play your chosen sounds, but you can go over the
limit of this example and even create a sound recorder that can save
onto sound formats."

and
http://www.vbsquare.com/php-bin/feedback.php?action=viewtopic&feedbacktopicid=770
Someone asking how to save to a wave file.

& look here on google groups :
http://groups.google.co.uk/groups?q=vb%20record%20wav%20file&hl=en&sa=N&tab=wg
loads of msgs about recording wav files.
Subject: Re: Visual Basic PCM Wav File Writing Source Code
From: rexrhino-ga on 15 May 2002 08:09 PDT
 
I have a very detailed description of the wav file format. The trouble
I have is figuring out which parts are little endian and big endian...
None of the wav format descriptions seem to have the right
information, so I have been trying myself, and all the sounds that I
have been saving have sounded scratchy and bad.

If I had the source code in C++, I could probably figure it out,
assuming that the big endian and little endian parts were correct.
Subject: Re: Visual Basic PCM Wav File Writing Source Code
From: unified-ga on 16 May 2002 17:01 PDT
 
Hello Rexrhino:

I have a feeling there is a problem with your source file. And, if you
already _have_ a detailed description of the WAV file format it
shouldn't be a problem. What I suggest is you should experiment a
little:

Find a program that DOES play your file correctly. You might want to
try
Sonicfoundry SoundForge (http://www.sonicfoundry.com). They have a
try-before-buy free demo version. Try to import your source data and
make it sound right by tweaking the import settings within SoundForge
(select .raw type when you import). Once you get the file playing,
save it as WAV and see what the right output format should be by
opening the resulting file with a hex editor.

Consider this: besides the big/little endian thing you might be using
signed ints instead of unsigned ints or vice-a-versa. That could, too,
be giving you terrible scratchy sounds. Another way to find out what
the problem is is to examine a working 44khz/16bit file to see what
byte ordering format it uses.

Obviously the header format of your file is correct: if you can hear
any sound and software not giving error messages. So, there is a
problem with the data. Try to examine the beginning of the data block
with a hex editor. Usually most files start with silence so they have
a "specific" look. Silence for a 44khz 16 bit stereo files looks like
00 00 00 00. So, if you are getting 00 80 00 80 or
ff 7f ff 7f for silence then you are using wrong sign format. Also,
WAV files (44khz/16bit/stereo) use normal (Intel) byte ordering i.e.
decimal number 32768 would be written as 00 80. This is also called
Little-endian ("little end first"), meaning less significant byte goes
first.

Also, you might want to check out URL
http://home.foni.net/~wkurz/dynaplot/applicationnotes/loadwav.htm

There you may find source code to READ WAV files of different formats.

Hope this helps. Good luck!

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy