1 Replies - 2891 Views - Last Post: 16 March 2010 - 02:05 AM Rate Topic: -----

#1 ameyakp  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 16-March 10

vox to wav convert

Posted 16 March 2010 - 02:01 AM

Hi all,
i want to create dll in c++ which will convert dialogic .vox file to .wav file.kindly suggest me for it.. i have one code in c++ for same but it is giving stdafx.h error.
// vox2wav.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include ".\vox2wav.h"


CVox2Wav::CVox2Wav(void)
{
	m_szLastError = NULL;

	m_nLastSample = 0;
	m_nCurrentStep = 0;

	//populate the vaw header
	m_sWavHeader.pcmfmt.wf.nChannels = 1;	//save only mono
	//the rest of the fields will be completed when Convert is called
}

CVox2Wav::~CVox2Wav(void)
{
	free(m_szLastError);
}

BOOL CVox2Wav::Convert(LPCTSTR szVoxFileName, LPCTSTR szWavFileName, int nSamplesPerSec, int nWavBitsPerSample)
{
	//free the last error, maybe the object is reused
	free(m_szLastError);

	//check the parameters
	if(nSamplesPerSec != 6000 && nSamplesPerSec != 8000)
	{
		//Dialogic only supports 6000 and 8000 vox
		m_szLastError = _tcsdup(_T("Only 6000 or 8000 samples per second are supported!"));
		return FALSE;
	}
	if(nWavBitsPerSample != 8 && nWavBitsPerSample != 16)
	{
		//we support only 8 or 16 bits per sample
		m_szLastError = _tcsdup(_T("Only 8 or 16 bits per sample are supported!"));
		return FALSE;
	}
	if((lstrlen(szVoxFileName) == 0) || (lstrlen(szWavFileName) == 0))
	{
		//we need the vox path
		m_szLastError = _tcsdup(_T("Vox path or Wav path is empty!"));
		return FALSE;
	}
	
	//check to see if we can open the files
	HANDLE hVOX = CreateFile(szVoxFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
	if(hVOX == INVALID_HANDLE_VALUE)
	{
		//the vox file cannot be created!
		m_szLastError = _tcsdup(_T("Vox file cannot be opened!"));
		return FALSE;
	}
	HANDLE hWAV = CreateFile(szWavFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
	if(hWAV == INVALID_HANDLE_VALUE)
	{
		//the vox file cannot be created!
		m_szLastError = _tcsdup(_T("Vav file cannot be created!"));
		CloseHandle(hVOX);
		return FALSE;
	}

	//now update the wav header and write it into the wav file
	int nVoxBytes = GetFileSize(hVOX, NULL);
	//assume that the GetFileSize does not fail if the file was opened successfully
	int nSamples = nVoxBytes * 2;	//each VOX byte has 2 samples!
	int nWavRawBytes = nSamples;
	if(nWavBitsPerSample == 16)
		nWavRawBytes *= 2;
	int nWavFileLen = nWavRawBytes + sizeof(MDT_PCM_WAV_HEADER);
	m_sWavHeader.dwChunkSize = nWavFileLen - 8;
	m_sWavHeader.pcmfmt.wf.nSamplesPerSec = nSamplesPerSec;
	m_sWavHeader.pcmfmt.wf.nAvgBytesPerSec = nSamplesPerSec * nWavBitsPerSample/8;	//it's actually SampleRate * NumChannels * BitsPerSample/8, but NumChannels is always 1
	m_sWavHeader.pcmfmt.wf.nBlockAlign = nWavBitsPerSample/8;	//it's actually NumChannels * BitsPerSample/8, but NumChannels is always 1
	m_sWavHeader.pcmfmt.wBitsPerSample = nWavBitsPerSample;
	m_sWavHeader.dataSize = nWavRawBytes;
	//write into the wav
	DWORD dwWritten = 0;
	if(WriteFile(hWAV, &m_sWavHeader, sizeof(MDT_PCM_WAV_HEADER), &dwWritten, NULL) == FALSE)
	{
		//cannot write to wav!
		m_szLastError = _tcsdup(_T("Cannot write to the wav file!"));
		CloseHandle(hVOX);
		CloseHandle(hWAV);
		DeleteFile(szWavFileName);
		return FALSE;
	}

	//start converting
	//we need a read buffer and a write buffer
	BYTE buffRead[VOX_DECODE_BUFFER_SIZE];	//read 8 K at a time
	short buffWrite[VOX_DECODE_BUFFER_SIZE*2];	//each vox byte has 2 samples which are decoded to a 12 bit value
	DWORD dwRead = VOX_DECODE_BUFFER_SIZE;
	while(dwRead == VOX_DECODE_BUFFER_SIZE)
	{
		if(ReadFile(hVOX, buffRead, VOX_DECODE_BUFFER_SIZE, &dwRead, NULL) == FALSE)
		{
			//cannot read from vox!
			m_szLastError = _tcsdup(_T("Cannot read from the vox file!"));
			CloseHandle(hVOX);
			CloseHandle(hWAV);
			DeleteFile(szWavFileName);
			return FALSE;
		}

		//process each byte
		int idxWrite = 0;
		for(DWORD idxRead = 0; idxRead < dwRead; idxRead++)
		{
			buffWrite[idxWrite++] = Decode((buffRead[idxRead]>>4)&0x0f);
			buffWrite[idxWrite++] = Decode(buffRead[idxRead]&0x0f);
		}

		//write the current decoded samples
		if(!WriteDecodedSamples(hWAV, nWavBitsPerSample, buffWrite, dwRead*2))
		{
			//cannot write to wav!
			m_szLastError = _tcsdup(_T("Cannot write to the wav file!"));
			CloseHandle(hVOX);
			CloseHandle(hWAV);
			DeleteFile(szWavFileName);
			return FALSE;
		}
	}

	//clear everything and exit
	CloseHandle(hVOX);
	CloseHandle(hWAV);

	return TRUE;
}

void CVox2Wav::GetLastError(LPTSTR szErrorBuff, int nErrorBuffLen)
{
	if(szErrorBuff == NULL || nErrorBuffLen < 1)
		return;

	if(m_szLastError == NULL)
	{
		szErrorBuff[0] = _T('\0');
		return;
	}

	lstrcpyn(szErrorBuff, m_szLastError, nErrorBuffLen-1);
	szErrorBuff[nErrorBuffLen-1] = _T('\0');
}

short CVox2Wav::Decode(BYTE nSample)
{
	//we should get only one nibble
	ASSERT((nSample & 0x0f) == nSample);

	short StepSize = VOX_STEP_SIZE[m_nCurrentStep];
	short Offset = StepSize/8;
	if (nSample & 0x01)
		Offset += StepSize/4;
	if (nSample & 0x02)
		Offset += StepSize/2;
	if (nSample & 0x04)
		Offset += StepSize;
	short diff = (nSample & 0x08) ? -Offset : Offset;
	short nRet = m_nLastSample + diff;

	//adjust the nRet to be 12 bits
	if(nRet > 2047)
		nRet = 2047;
	if(nRet < -2048)
		nRet = -2048;

	//calculate the next step
	m_nLastSample = nRet;
	m_nCurrentStep += VOX_STEP_ADJUST[nSample&0x07];
	if(m_nCurrentStep < 0)
		m_nCurrentStep = 0;
	if(m_nCurrentStep > VOX_NR_STEPS-1)
		m_nCurrentStep = VOX_NR_STEPS-1;
	
	return nRet;
}

BOOL CVox2Wav::WriteDecodedSamples(HANDLE hWav, int nWavBitsPerSample, short* pSamples, int nrSamples)
{
	if(nWavBitsPerSample == 16)
	{
		//it's simpler... just convert in place the 12 bit to 16 bit and write the buffer
		for(int idx = 0; idx < nrSamples; idx++)
			pSamples[idx] *= 16;	//just move to the left 4 bits!
		//write the buffer
		DWORD dwWritten = 0;
		if(WriteFile(hWav, pSamples, nrSamples*sizeof(short), &dwWritten, NULL) == FALSE)
			return FALSE;
		if(dwWritten != nrSamples*sizeof(short))
			return FALSE;
		return TRUE;
	}
	else if(nWavBitsPerSample == 8)
	{
		//we have to allocate a 8 bit buffer in which to transform the samples from 12 to 8 bit
		//we know that the number of samples is maximum VOX_DECODE_BUFFER_SIZE*2
		ASSERT(nrSamples <= VOX_DECODE_BUFFER_SIZE*2);
		BYTE buff8bit[VOX_DECODE_BUFFER_SIZE*2];
		for(int idx = 0; idx < nrSamples; idx++)
		{
			//shift the sample value right 4 bits
			//but add 128 because stupid 8 bit wav is not from -128 to 127, but from 0 to 255
			pSamples[idx] /= 32;	//why not 16, which is 4 bits? maybe because we add 128
			buff8bit[idx] = (BYTE)(pSamples[idx] + 128);
		}
		//write the buffer
		DWORD dwWritten = 0;
		if(WriteFile(hWav, buff8bit, nrSamples*sizeof(BYTE), &dwWritten, NULL) == FALSE)
			return FALSE;
		if(dwWritten != nrSamples*sizeof(BYTE))
			return FALSE;

		return TRUE;
	}
	else
		return FALSE;
}




#pragma once

#include <Windows.h>
#include <assert.h>
#include <conio.h>
#include <MMSystem.h>

struct MDT_PCM_WAV_HEADER
{
	MDT_PCM_WAV_HEADER()
	{
		//initialize what we can by default
		RIFF[0] = 'R';
		RIFF[1] = 'I';
		RIFF[2] = 'F';
		RIFF[3] = 'F';

		WAVE[0] = 'W';
		WAVE[1] = 'A';
		WAVE[2] = 'V';
		WAVE[3] = 'E';

		fmt[0] = 'f';
		fmt[1] = 'm';
		fmt[2] = 't';
		fmt[3] = ' ';
		fmtSize = 16;	//it's PCM

		pcmfmt.wf.wFormatTag = WAVE_FORMAT_PCM;

		data[0] = 'd';
		data[1] = 'a';
		data[2] = 't';
		data[3] = 'a';

		//the rest of the fields will be completed as needed
	}

	//header
	char RIFF[4];	//here should be "RIFF"
	DWORD dwChunkSize;	//here should be filesize-8
	char WAVE[4];	//here should be "WAVE"

	//the "fmt " chunk
	char fmt[4];	//here should be "fmt "
	DWORD fmtSize;	//the size of the "fmt " chunk (should be 16 for PCM wavs)
	PCMWAVEFORMAT pcmfmt;

	//the "data" subchunk
	char data[4];	//here should be "data"
	DWORD dataSize;	//the size of the "data" chunk = NumSamples * NumChannels * BitsPerSample/8
					//also, it's the filesize-sizeof(MDT_PCM_WAV_HEADER)
};

const int VOX_DECODE_BUFFER_SIZE = 64*1024;
const int VOX_NR_STEPS = 49;
const short VOX_STEP_SIZE[VOX_NR_STEPS] = 
{
	16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
	41, 45, 50, 55, 60, 66, 73, 80, 88, 97,
	107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
	279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
	724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552,
};
const short VOX_STEP_ADJUST[8] = 
{
	-1,
	-1,
	-1,
	-1,
	2,
	4,
	6,
	8,
};

//THIS IS NOT MULTITHREADED!!!!!
class CVox2Wav
{
public:
	CVox2Wav(void);
	~CVox2Wav(void);

	BOOL Convert(LPCTSTR szVoxFileName, LPCTSTR szWavFileName, int nSamplesPerSec, int nWavBitsPerSample);
	void GetLastError(LPTSTR szErrorBuff, int nErrorBuffLen);

protected:
	TCHAR*	m_szLastError;

	MDT_PCM_WAV_HEADER m_sWavHeader;

	int	m_nCurrentStep;
	short	m_nLastSample;

	//Methods
	short Decode(BYTE nSample);
	BOOL WriteDecodedSamples(HANDLE hWav, int nWavBitsPerSample, short* pSamples, int nrSamples);
};





Is This A Good Question/Topic? 0
  • +

Replies To: vox to wav convert

#2 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: vox to wav convert

Posted 16 March 2010 - 02:05 AM

What's the error?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1