// WaveForm.cpp: Implementierung der Klasse CWaveForm.
//
//////////////////////////////////////////////////////////////////////

#include "WaveForm.h"
#define STRICT
#include <windows.h>
#include <mmsystem.h>
#include <dxerr8.h>
#include <dsound.h>
#include "DSUtil.h"
#include "DXUtil.h"

//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define WAVEFORMOVER  2048

#define SAFE_FREE(p)    { if(p) { free(p);        (p)=NULL; } }
#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }


//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
// requires 16bit Stereo Data
CWaveForm::CWaveForm()
{
	m_pWaveForm = NULL;
	WaveData = NULL;
}

CWaveForm::~CWaveForm()
{
	SAFE_FREE(m_pWaveForm);
}

//////////////////////////////////////////////////////////////////////
// Methoden
//////////////////////////////////////////////////////////////////////

void CWaveForm::LoadWaveAndConvert(char* strFileName )
{
    HRESULT		hr;
    CWaveFile	waveFile;
	DWORD		dwSizeRead = 0;


    // Load the wave file
    if( FAILED( hr = waveFile.Open( strFileName, NULL, WAVEFILE_READ ) ) )
    {
        DXTRACE_ERR( TEXT("Open"), hr );
        waveFile.Close();
//m        SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Bad wave file.") );
        return;
    }

    if( waveFile.GetSize() == 0 )
    {
        waveFile.Close();
//m        SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Wave file blank.") );
        return;
    }

	WaveData = malloc(waveFile.GetSize());
    ZeroMemory(WaveData, waveFile.GetSize());

	waveFile.Read((BYTE*) WaveData, waveFile.GetSize(), &dwSizeRead);

	ConvertData(WaveData, waveFile.GetSize());
	m_RawSize = waveFile.GetSize();

//    SAFE_FREE(WaveData);
	waveFile.Close();
}


void CWaveForm::LoadWave(char* strFileName )
{
    HRESULT		hr;
    CWaveFile	waveFile;
	DWORD		dwSizeRead = 0;


    // Load the wave file
    if( FAILED( hr = waveFile.Open( strFileName, NULL, WAVEFILE_READ ) ) )
    {
        DXTRACE_ERR( TEXT("Open"), hr );
        waveFile.Close();
//m        SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Bad wave file.") );
        return;
    }

    if( waveFile.GetSize() == 0 )
    {
        waveFile.Close();
//m        SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Wave file blank.") );
        return;
    }

	WaveData = malloc(waveFile.GetSize());
    ZeroMemory(WaveData, waveFile.GetSize());

	waveFile.Read((BYTE*) WaveData, waveFile.GetSize(), &dwSizeRead);

//	ConvertData(WaveData, waveFile.GetSize());
	m_RawSize = waveFile.GetSize();

//    SAFE_FREE(WaveData);
	waveFile.Close();
}


void CWaveForm::ConvertData(void* WaveData, int WaveSize)
{

	dwWaveFormSize = WaveSize / 4;
	SAFE_FREE(m_pWaveForm);
	m_pWaveForm = malloc(dwWaveFormSize + WAVEFORMOVER);
	FillMemory( (small*) m_pWaveForm, dwWaveFormSize + WAVEFORMOVER, (small) 0);
	for (int i = 0; i < dwWaveFormSize; i++) {
		((small*)m_pWaveForm)[i]  = (small) ((((__int16*)WaveData)[i*2] * 0.5+ ((__int16*)WaveData)[i*2+1] * 0.5)/256.0);
	}
	
//    SAFE_FREE(WaveData);
}


void* CWaveForm::GetWaveForm() {
	return m_pWaveForm;
}

void CWaveForm::FreeRawWaveForm() {
    SAFE_FREE(WaveData);
}
void* CWaveForm::GetRawWaveForm() {
	return WaveData;
}
int CWaveForm::GetRawSize() {
	return m_RawSize;
}

bool CWaveForm::LoadFromFile(char*  strFileName){
    HANDLE		hFile;
	DWORD		dwSizeRead = 0;
	DWORD		fileSize = 0;



	hFile = CreateFile(strFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	
	if(INVALID_HANDLE_VALUE == hFile)
    {
//        CloseFile(hFile);
        return false;
    }

	fileSize = dwWaveFormSize = GetFileSize(hFile, NULL);

	if( fileSize == 0 )
    {
        CloseHandle(hFile);
        return false;
    }

	m_pWaveForm = malloc(fileSize);
    ZeroMemory(m_pWaveForm, fileSize);

	ReadFile(hFile, m_pWaveForm, fileSize, &dwSizeRead, NULL);

	CloseHandle(hFile);
	return true;
}

void CWaveForm::SaveToFile(char*  strFileName) {
    HANDLE		hFile;
	DWORD		dwSizeWritten = 0;

	hFile = CreateFile(strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
	
	if(INVALID_HANDLE_VALUE == hFile)
    {
//        CloseFile(hFile);
        return;
    }
	WriteFile(hFile, m_pWaveForm, dwWaveFormSize, &dwSizeWritten, NULL);

	CloseHandle(hFile);
	return;
}
