0
0

Hi all,

I need some help with using the buffers in the readcallback of a custom dsp that I have been creating. Basically the idea is to write the data out into one minute wav files.

My problem is that I am not understanding what the float values in the buffer represent, or how to convert that back to data that can be written to disk with a wav header.

Could anyone point me in the right direction with this?

  • You must to post comments
0
0

his is probably getting a bit off topic now, but at least if it is here you have some context.

I was looking at setting the software format on the fmod system object to change the sample rate to 22050hz. So

[code:1rnd815q]system.setSoftwareFormat(22050, SOUND_FORMAT.PCM16, 2, 0, DSP_RESAMPLER.LINEAR);[/code:1rnd815q]

Then writing that data out in the DSP callback. But when I do this I seem to be getting 44100hz. At leat when I write out the file as a wav with 44100 as its rate it sounds right, but when I use 22050 or 48000 it does not.

Can you think of any reason why this would happen?

  • You must to post comments
0
0

For a wav writer, check the ‘record’ example.
For info on the float data, it is -1.0 to +1.0.

To conver this to 16bit PCM data you have to multiply by 32767

  • You must to post comments
0
0

if you use system.getSoftwareFormat after init you might find the samplerate has been ignored, if it is not a directsound output. Some operatings systems wont let you change the format.

  • You must to post comments
0
0

So should I loop through it with something like this?

bw being a binaryWriter that writes the short to a file?

[code:2mdqgfud]

          float* inbuffer = (float*)inbuf.ToPointer();
          float* outbuffer = (float*)outbuf.ToPointer();

            for (count = 0; count < length * inchannels ; count++)
            {
                float t = inbuffer[count];
                outbuffer[count] = inbuffer[count];
                if (t >= 1.0f)
                {
                   bw.Write(32767);
                }
                else if (t <= -1.0f)
                {
                   bw.Write(-32768);
                }
                else
                {
                    bw.Write((Int16)(t * 32767));
                }

[/code:2mdqgfud]

This does not seem to work for me. But I suspect that is something fundamental that I am missing…

  • You must to post comments
0
0

I suspect it is the former.

It is not too important as I can easily downsample from 44100. Thanks for the help Brett.

  • You must to post comments
0
0

that code looks right to me, not knowing what bw does internally.

  • You must to post comments
0
0

[quote="Caelum":2lwnr19l]My problem was that the BinaryWriter was not converting the shorts to 2 bytes.

So I had to do this:

            [code:2lwnr19l]
            float* inbuffer = (float*)inbuf.ToPointer();
            float* outbuffer = (float*)outbuf.ToPointer();

            List<short> bufferToWrite = new List<short>();
            for (count = 0; count < length * inchannels; count++)
            {
                float t = inbuffer[count];
                outbuffer[count] = inbuffer[count];
                if (t >= 1.0f)
                {
                    bufferToWrite.Add(32767);
                }
                else if (t <= -1.0f)
                {
                    bufferToWrite.Add(-32768);
                }
                else
                {
                    bufferToWrite.Add((short)(t * 32767));
                }
            }

            List<byte> b = new List<byte>();
            for (int i = 0; i < bufferToWrite.Count; i++)
            {
                b.AddRange(BitConverter.GetBytes(bufferToWrite[i]));
            }
            stream.Write(b.ToArray(), 0, b.Count);
            bufferToWrite.Clear();[/code:2lwnr19l]

That outputs the raw PCM data that I was after.[/quote:2lwnr19l]

Hi can you convert your code in C++?
Regards,
Franco

  • You must to post comments
0
0

My problem was that the BinaryWriter was not converting the shorts to 2 bytes.

So I had to do this:

            [code:46qz0hlh]
            float* inbuffer = (float*)inbuf.ToPointer();
            float* outbuffer = (float*)outbuf.ToPointer();

            List<short> bufferToWrite = new List<short>();
            for (count = 0; count < length * inchannels; count++)
            {
                float t = inbuffer[count];
                outbuffer[count] = inbuffer[count];
                if (t >= 1.0f)
                {
                    bufferToWrite.Add(32767);
                }
                else if (t <= -1.0f)
                {
                    bufferToWrite.Add(-32768);
                }
                else
                {
                    bufferToWrite.Add((short)(t * 32767));
                }
            }

            List<byte> b = new List<byte>();
            for (int i = 0; i < bufferToWrite.Count; i++)
            {
                b.AddRange(BitConverter.GetBytes(bufferToWrite[i]));
            }
            stream.Write(b.ToArray(), 0, b.Count);
            bufferToWrite.Clear();[/code:46qz0hlh]

That outputs the raw PCM data that I was after.

  • You must to post comments
0
0

If it is Visual C++ that you are converting it too, then it is pretty simple to convert it since the syntax is almost the same. Just remove the first two lines, since they would not be needed in C++.

So it would be something like this:

[code:1u2pnbt3]int count;

list<short> bufferToWrite = new list<short>();


for (count = 0; count < length * inchannels; count++) 
{ 
    float t = inbuffer[count];
    outbuffer[count] = inbuffer[vount];

    if(t >= 1.0f)
    {
        bufferToWrite.push_back(32767);
    }
    else if( t <= -1.0f)
    {
        bufferToWrite.push_back(-32767);
    }
    else
    {
        bufferToWrite.push_back(t * 32767);
    }      
} 

list<byte> b = new list<b>();

while(bufferToWrite.size > 0)
{
    short shortToWrite = bufferToWrite.pop_front();
    b.push_back(BitConverter::GetBytes(shortToWrite));
}

//Write b to file.
[/code:1u2pnbt3]

That is abut the limit of what I can do in C++ off the top of my head though :). I have not actually written much more then a few hello world type apps in it. I think that the only bit you would not have if it is not VC++ would be the BitConverter, so you would need to convert the shorts to bits so that they could be written out. It could also be made a bit more efficient by removing the second loop and converting the shorts in the first loop.

  • You must to post comments
0
0

Thanks for the help :).

  • You must to post comments
0
0

It seems that when using this code the outputed wav file is about 20 odd seconds longer then the original file.

Does anyone have any idea why this would happen?

  • You must to post comments
0
0

Probably because it was the time between the call to System::init and System::close/release? The dsp system is running as soon as you call init, not just when you play sounds.

  • You must to post comments
0
0

Wouldn’t that mean that I would have a heap of silence at the start and end of the file?

This is sort of mixed in with it, so it does actully sound a bit slower then the original as well.

  • You must to post comments
0
0

Oh thats what I thought you meant.

Well in that case you’re probably just writing out the wave with a different frequency than the output of fmod. Ie fmod runs at 48khz by default and you probably wrote out the wav as 44.1khz

  • You must to post comments
0
0

Thanks Brett, that was exactly the problem, I thought that Fmod run at 44100 for some reason.

Thanks again.

  • You must to post comments
Showing 15 results
Your Answer

Please first to submit.