How do I write 8, 24, 32-bit .WAV files?

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

I have an array of numbers that are of the type double. I run through a for-loop and am able to right 16-bit mono .WAV files. I use code that resembles the following:

Code: Select all

double y, t=0;
short audio16;
FILE *outFile;
	  
// insert useful code here
		
for(i=0;i<100;i++){
	y=sin(t);
	t+=0.1;
	audio16 = floor(y*32767.0+0.5);
	fwrite(&audio16,2,1,outFile);
	}
This seems to work. The variable audio16 is of the type short which happen to be 16-bit. fwrite takes the value help by audio16 and writes it to two bytes of the output outFile.

What do I do if I want to write 8, 24, 32-bit audio? If I have a variable, say audio24, that is 24-bit, what data type do I use to represent it? This is not as important, but how in the world do I write 20-bit audio?

Post

Use libsndfile.

I say this as a coder committed to rolling his own whenever possible.

Use libsndfile.
Image
Don't do it my way.

Post

Microsoft got some info on that in the MSDN. In principle, 20bit is like 24bit, but with the 4 least significant bits being empty. The samples are always using full bytes.
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post

Borogove wrote:Use libsndfile.

I say this as a coder committed to rolling his own whenever possible.

Use libsndfile.
I don't know how to use libsndfile either. I don't expect that it would be any easier. I can break a 24-bit sample into 16 and 8 bit chunks, but I'm not sure just how to break it.

Post

halfpower wrote:I don't know how to use libsndfile either. I don't expect that it would be any easier.
:cry:
Image
Don't do it my way.

Post

Come on Boro. You've caught my attention anyhow. Is this a DLL you link with, or do you compile the source in? Is the interface pretty easy?

Post

mister: It's easy, you get the c sources, just google it :)

http://www.mega-nerd.com/libsndfile/

Post

I can write 8, 16, and 32-bit audio to disk. I'm stuck on 24. I haven't figured out how to represent a 24-bit data type.

libsndfile might work, but I would probably have to join the mailing list to figure out the syntax. I need an example or something to look at.

Post

the .wav format isnt designed to take any type other than: 8 bit unsigned, 16 bit signed, 32 bit float.

other formats should not be expected to work, and the float format isnt supported nearly as often as the other two.

if you want to write variable length formats for your own purposes, you need to find another format (use libsndfile) or write your own format.

it isnt difficult to work with variable bit length samples, but that is advanced stuff in line with encryption/compression. you're not even writing a .wav file there as far as i can see, you're just spitting out raw sample data into a plain binary file.

Post

Like 32bit, only take the 3 most significant bytes... from memory, simply use something like

Code: Select all

union
  {
  long l32bit;
  struct
    {
#if BIGENDIAN // Motorola, PowerPC, ...
    unsigned char bRelevant[3];
    unsigned char bIgnore;
#else // x86
    unsigned char bIgnore;
    unsigned char bRelevant[3];
#endif
    } b;
  } work;

// convert float to 24-bit:
work.l32bit = (long)(fvalue * 2147483647.f);
memcpy(target, work.b.bRelevant, 3);

// convert 24-bit to float:
memcpy(work.b.bRelevant, target, 3);
fValue = (float)work.l32bit / 2147483647.f;
... or something like that. The above is a very simplistic approach.
Last edited by arakula on Fri Oct 13, 2006 6:12 pm, edited 1 time in total.
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post

aciddose wrote:the .wav format isnt designed to take any type other than: 8 bit unsigned, 16 bit signed, 32 bit float.

other formats should not be expected to work, and the float format isnt supported nearly as often as the other two.
aciddose, I really have to know: do you do this on purpose?

24 bit wav is well defined.
Image
Don't do it my way.

Post

i've been through this discussion before, i'm not sure if it was with you or somebody else, multiple times i think. i know it is defined, i didnt say it wasnt defined. what i said was the original intention of the format was to store only those three types of data, and they are the only types of data which are most often supported.

of course you can use 100s of compression formats with riff wave files, but a majority of the time software wont load them. 24bit works, but it is even less often you'll find it working correctly than you'll find 32bit float working. so, i'd suggest not to use it, just go with 32bit float if you're going to bother using more than 16bit.

of course maybe some people disagree regarding this last thing i've said, but it is a fact that 24bit is less supported than 32bit float. in my experiance, 24bit is very rarely supported, not just slightly less often supported.

beside that, it seems the op wasnt talking about riff wave anyway unless he asserts that he was. in such case, there are multiple ways to store any number of bits and so to answer the question is very difficult. the "use libsndfile" suggestion was the best answer.

Post Reply

Return to “DSP and Plugin Development”