Compare commits

...
Sign in to create a new pull request.

2 commits
master ... riff

Author SHA1 Message Date
Andrea Odetti
0b37d9a022 Riff file generation: fix sizes.
myTotalNumberOfBytesWritten is actually the number of samples written, and not the file size.

This means that both total and data are off by the size of the header.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-27 17:05:31 +01:00
Andrea Odetti
42c68677b4 Riff: make code reusable.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-27 16:53:13 +01:00
2 changed files with 94 additions and 42 deletions

View file

@ -29,20 +29,36 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#include "Riff.h"
static HANDLE g_hRiffFile = INVALID_HANDLE_VALUE;
static DWORD dwTotalOffset;
static DWORD dwDataOffset;
static DWORD g_dwTotalNumberOfBytesWritten = 0;
static unsigned int g_NumChannels = 2;
int RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels)
namespace
{
g_hRiffFile = CreateFile(pszFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
RiffOutput g_RiffOutput; // default output
}
if(g_hRiffFile == INVALID_HANDLE_VALUE)
RiffOutput::RiffOutput()
: myRiffFile(INVALID_HANDLE_VALUE)
, myTotalOffset(0)
, myDataOffset(0)
, myTotalNumberOfSampleBytesWritten(0)
, myNumChannels(0)
{
}
RiffOutput::~RiffOutput()
{
FinishWriteFile();
}
int RiffOutput::InitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels)
{
FinishWriteFile(); // avoid leaks if the file was already open
myRiffFile = CreateFile(pszFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (myRiffFile == INVALID_HANDLE_VALUE)
return 1;
g_NumChannels = NumChannels;
myTotalNumberOfSampleBytesWritten = 0;
myNumChannels = NumChannels;
//
@ -51,75 +67,76 @@ int RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned in
DWORD dwNumberOfBytesWritten;
WriteFile(g_hRiffFile, "RIFF", 4, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, "RIFF", 4, &dwNumberOfBytesWritten, NULL);
temp32 = 0; // total size
dwTotalOffset = SetFilePointer(g_hRiffFile, 0, NULL, FILE_CURRENT);
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
myTotalOffset = SetFilePointer(myRiffFile, 0, NULL, FILE_CURRENT);
WriteFile(myRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
WriteFile(g_hRiffFile, "WAVE", 4, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, "WAVE", 4, &dwNumberOfBytesWritten, NULL);
//
WriteFile(g_hRiffFile, "fmt ", 4, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, "fmt ", 4, &dwNumberOfBytesWritten, NULL);
temp32 = 16; // format length
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
temp16 = 1; // PCM format
WriteFile(g_hRiffFile, &temp16, 2, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, &temp16, 2, &dwNumberOfBytesWritten, NULL);
temp16 = NumChannels; // channels
WriteFile(g_hRiffFile, &temp16, 2, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, &temp16, 2, &dwNumberOfBytesWritten, NULL);
temp32 = sample_rate; // sample rate
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
temp32 = sample_rate * 2 * NumChannels; // bytes/second
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
temp16 = 2 * NumChannels; // block align
WriteFile(g_hRiffFile, &temp16, 2, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, &temp16, 2, &dwNumberOfBytesWritten, NULL);
temp16 = 16; // bits/sample
WriteFile(g_hRiffFile, &temp16, 2, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, &temp16, 2, &dwNumberOfBytesWritten, NULL);
//
WriteFile(g_hRiffFile, "data", 4, &dwNumberOfBytesWritten, NULL);
WriteFile(myRiffFile, "data", 4, &dwNumberOfBytesWritten, NULL);
temp32 = 0; // data length
dwDataOffset = SetFilePointer(g_hRiffFile, 0, NULL, FILE_CURRENT);
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
myDataOffset = SetFilePointer(myRiffFile, 0, NULL, FILE_CURRENT);
WriteFile(myRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
return 0;
}
int RiffFinishWriteFile()
int RiffOutput::FinishWriteFile()
{
if(g_hRiffFile == INVALID_HANDLE_VALUE)
if(myRiffFile == INVALID_HANDLE_VALUE)
return 1;
//
UINT32 temp32;
DWORD dwNumberOfBytesWritten;
temp32 = g_dwTotalNumberOfBytesWritten - (dwTotalOffset + 4);
SetFilePointer(g_hRiffFile, dwTotalOffset, NULL, FILE_BEGIN);
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
temp32 = g_dwTotalNumberOfBytesWritten - (dwDataOffset + 4);
SetFilePointer(g_hRiffFile, dwDataOffset, NULL, FILE_BEGIN);
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
DWORD fileSize = SetFilePointer(myRiffFile, 0, NULL, FILE_END);
DWORD temp32 = fileSize - (myTotalOffset + 4);
SetFilePointer(myRiffFile, myTotalOffset, NULL, FILE_BEGIN);
WriteFile(myRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
return CloseHandle(g_hRiffFile);
SetFilePointer(myRiffFile, myDataOffset, NULL, FILE_BEGIN);
WriteFile(myRiffFile, &myTotalNumberOfSampleBytesWritten, 4, &dwNumberOfBytesWritten, NULL);
int result = CloseHandle(myRiffFile);
myRiffFile = INVALID_HANDLE_VALUE;
return result;
}
int RiffPutSamples(const short* buf, unsigned int uSamples)
int RiffOutput::PutSamples(const short* buf, unsigned int uSamples)
{
if(g_hRiffFile == INVALID_HANDLE_VALUE)
if(myRiffFile == INVALID_HANDLE_VALUE)
return 1;
//
@ -127,13 +144,29 @@ int RiffPutSamples(const short* buf, unsigned int uSamples)
DWORD dwNumberOfBytesWritten;
BOOL bRes = WriteFile(
g_hRiffFile,
myRiffFile,
buf,
uSamples * sizeof(short) * g_NumChannels,
uSamples * sizeof(short) * myNumChannels,
&dwNumberOfBytesWritten,
NULL);
g_dwTotalNumberOfBytesWritten += dwNumberOfBytesWritten;
myTotalNumberOfSampleBytesWritten += dwNumberOfBytesWritten;
return 0;
}
int RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels)
{
return g_RiffOutput.InitWriteFile(pszFile, sample_rate, NumChannels);
}
int RiffFinishWriteFile()
{
return g_RiffOutput.FinishWriteFile();
}
int RiffPutSamples(const short* buf, unsigned int uSamples)
{
return g_RiffOutput.PutSamples(buf, uSamples);
}

View file

@ -1,5 +1,24 @@
#pragma once
class RiffOutput
{
public:
RiffOutput();
~RiffOutput();
int InitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels);
int FinishWriteFile();
int PutSamples(const short* buf, unsigned int uSamples);
private:
HANDLE myRiffFile;
DWORD myTotalOffset;
DWORD myDataOffset;
DWORD myTotalNumberOfSampleBytesWritten;
unsigned int myNumChannels;
};
// these operate in the "global" RiffOutput object
int RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels);
int RiffFinishWriteFile();
int RiffPutSamples(const short* buf, unsigned int uSamples);