Know any good audio formats?

Started by
4 comments, last by wazoo69 18 years, 10 months ago
I've been trying to decide on what audio format I want to use with DirectSound. I'm not to much into writing long routines for loading WAV files using MMIO. I really hate MS examples because their functions are huge and other reasons. I don't need audio files that support comments. The commenting info really doesn't do me any good in a game does it? The only time it would was if I were using MP3s or some sort for music tracks and I wanted to display to the user what track was playing with the artist's name. Other then that, I can do with out a lot of the BS with WAV for MP3 crap. So I'm looking for a good audio format that cuts right to the chase and gives me what I want-sound! I was leaning towards EA's format, but I've been wondering what else might give me what I need. Would any of you happen to know of any formats? Please keep in mind of what I've already said. I only want sound data and nothing else. I'm also limited on cash so I don't have to have to pay for product licensing when I'm only using it for a simple game. NOTE: The reason I say that is because some sound systems required a license fee and do not release their format specifications but provide good APIs used in many commercial products. Examples-> Miles or Bink.
Take back the internet with the most awsome browser around, FireFox
Advertisement
Ummmm, most .wav files are super easy to load (unless they're in some off-the-wall format or something). Just write a wav loader yourself, it's really simple (MUCH easier than loading, say, .bmp files).
------------------------------BASIC programmers don't die, they just GOSUB and don't return.
That may be so but if the file contains comments then you have to read in extra bytes and all the crap. I've already got a WAV loader but I can only use if with sounds that are not commented and pure PCM format. That means no extra bytes and just the sound data.

Because I don't have a program that rips out comments or converts a WAV to a pure PCM WAV, I need a different format then that only supports sounds. I chose EA;s format because I know it's good sound from the various NFSs.

Bit I'm wanting something a little more easier or more capable. Like, high res sounds that are easy to stream. I'm not to familiar with DS so I need something really simple and not to complex.

All I need is sound data. I need a format that just has that and nothing else.
Take back the internet with the most awsome browser around, FireFox
Quote:Original post by GarlandIX
Ummmm, most .wav files are super easy to load (unless they're in some off-the-wall format or something). Just write a wav loader yourself, it's really simple (MUCH easier than loading, say, .bmp files).

I would be interested in knowing your method of doing this. My wav file loading code is horribly complex for such a simple task.

Anyway, here's my entire routine to load a wav. I'm not going to try to clean it up, so some things may need explained further. Just ask away. Also, this loads the file from memory. You would either need to change some of it around, load your file completely into memory, or get a pointer-to-harddrive thingo [smile]
// Prepare to loadWAVEFORMATEX wfx;File.Open(...);Zero( &wfx );// Prepare wav file readingHMMIO		wave_handle;MMCKINFO		parent_chunk;MMCKINFO		child_chunk;parent_chunk.ckid		= 0;parent_chunk.cksize	= 0;parent_chunk.fccType	= 0;parent_chunk.dwDataOffset	= 0;parent_chunk.dwFlags	= 0;child_chunk = parent_chunk;// Read Data from wav fileMMIOINFO info;Zero( &info );info.pchBuffer = (CHAR*) File.GetMemoryPtr();info.fccIOProc = FOURCC_MEM;info.cchBuffer = File.GetSize();wave_handle = mmioOpen( NULL, &info, MMIO_READ );if(!wave_handle) return 0;parent_chunk.fccType	= mmioFOURCC('W','A','V','E');child_chunk.ckid		= mmioFOURCC('f','m','t',' ');if( mmioDescend( wave_handle, &parent_chunk, NULL, MMIO_FINDRIFF )||  mmioDescend( wave_handle, &child_chunk, &parent_chunk, 0 )||  mmioRead( wave_handle, (CHAR*)&wfx, sizeof(WAVEFORMATEX) ) != sizeof(WAVEFORMATEX)||  wfx.wFormatTag != WAVE_FORMAT_PCM||  mmioAscend( wave_handle, &child_chunk, 0 ) ){	Log("Incorrect sound type: %s", filename );	mmioClose(wave_handle,0);	return 0;}child_chunk.ckid = mmioFOURCC('d','a','t','a');if(mmioDescend(wave_handle, &child_chunk, &parent_chunk, MMIO_FINDCHUNK)){	Log("Sound Error: %s", filename );	mmioClose(wave_handle,0);	return 0;}// Setup buffer description + create soundDSBUFFERDESC desc;Zero( &desc );desc.dwSize = sizeof( DSBUFFERDESC );desc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_STATIC | DSBCAPS_CTRLPAN				| DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;desc.dwBufferBytes = child_chunk.cksize;desc.lpwfxFormat = &wfx;SourceSound = SoundEng->CreateBuffer( &desc );// Lock and read the buffer inif( !SourceSound ){	Log("Unable to create sound buffer");}else{	BOOL was_error = FALSE;	BYTE *DataA=NULL, *DataB=NULL;	ULONG SizeA=0, SizeB=0;	hVal = SourceSound->Lock( 0, child_chunk.cksize, (void**)&DataA, &SizeA,				(void**)&DataB, &SizeB, DSBLOCK_FROMWRITECURSOR );	if( FAILED(hVal) )	{		was_error = TRUE;		Log("[error] Unable to lock sound buffer to copy wave data");	}	else	{		if( SizeA != mmioRead( wave_handle, (CHAR*)DataA, SizeA ) )		{			was_error = TRUE;			Log("[error] Unable to read sound data (A)");		}		else if( SizeB != mmioRead( wave_handle, (CHAR*)DataB, SizeB ) )		{			was_error = TRUE;			Log("[error] Unable to read sound data (B)");		}		else		{			// Close and unlock			mmioClose(wave_handle,0);			SourceSound->Unlock(DataA,SizeA,DataB,SizeB);			Size = child_chunk.cksize;			nSamples = ( Size * 8 ) / ( wfx.wBitsPerSample * wfx.nChannels );			Length = ( nSamples * 1000 ) / wfx.nSamplesPerSec;		}	}	if( was_error && SourceSound )		SourceSound->Release();}
That looks like the SDK sample! Loading if from memory huh? I didn't think of that because it may be easier to laod a file once it's loaded into a buffer. The over all tasks are similar but it just seams easier to me unless I had to stream in a WAV.

When I was studying the SDK sample, I notices a few things and it seamed more clear to me. First, this is the method I use so far.

typedef struct st_WAVEINFO * LPWAVEINFO, * PWAVEINFO ;typedef struct st_WAVEINFO {	CHAR				szRiffSig[ 4 ] ;	DWORD				dwChunkSize ;	CHAR				szWaveSig[ 4 ] ;	CHAR				szFrmtSig[ 4 ] ;	WORD				wFormatChunkSize ;	WORD				wFormatTag ;	WORD				wChannels ;	DWORD				dwSampleRate ;	DWORD				dwBytesPerSec ;	WORD				wBlockAlign ;	WORD				wBitsPerSample ;	CHAR				szDataSig[ 4 ] ;	DWORD				dwDataSize ;} WAVEINFO ;// ---------------------------------------------------------------------------- //// Name		: DSLoadWaveFile( )// Desc		: Loads a .WAV audio file into DirectSound// ---------------------------------------------------------------------------- //HRESULT __stdcall DSLoadWaveFile( LPCSTR lpszFileName, LPDIRECTSOUNDBUFFER8 lpDSBOutput ){	LPDIRECTSOUNDBUFFER				 lpDSBSound	= NULL ;	WAVEFORMATEX					 WfEx ;	DSBUFFERDESC					 DSbd ;	DWORD							 dwSize1	= 0L,									 dwSize2	= 0L ;	LPVOID							 pData1		= NULL,									 pData2		= NULL ;	WAVEINFO						 Info ;	FILE*							 pFile		= NULL ;	HRESULT							 hRet ;	if ( NULL == ( pFile = fopen( lpszFileName, "rb" ) ) )	{		return ( E_FAIL ) ;	}	fread( &Info, sizeof( WAVEINFO ), 1, pFile ) ;	if ( memcpy( Info.szRiffSig, "RIFF", 4 ) ||		 memcpy( Info.szWaveSig, "WAVE", 4 ) ||		 memcpy( Info.szFrmtSig, " fmt", 4 ) ||		 memcpy( Info.szDataSig, "data", 4 ) )	{		fclose ( pFile  ) ;		return ( E_FAIL ) ;	}	memset( &WfEx, 0, sizeof( WAVEFORMATEX ) ) ;	WfEx.wFormatTag					 = WAVE_FORMAT_PCM ;	WfEx.nChannels					 = Info.wChannels ;	WfEx.nSamplesPerSec				 = Info.dwSampleRate ;	WfEx.wBitsPerSample				 = Info.wBitsPerSample ;	WfEx.nBlockAlign				 = Info.wBlockAlign ;	WfEx.nAvgBytesPerSec			 = ( WfEx.nSamplesPerSec * WfEx.nBlockAlign ) ;	memset( &DSbd, 0, sizeof( DSBUFFERDESC ) ) ;	DSbd.dwSize						 = sizeof( DSBUFFERDESC ) ;	DSbd.dwBufferBytes				 = Info.dwDataSize ;	DSbd.lpwfxFormat				 = &WfEx ;	if ( FAILED( hRet = g_lpDS->CreateSoundBuffer( &DSbd, &lpDSBSound, NULL ) ) )	{		fclose ( pFile ) ;		return ( hRet  ) ;	}	if ( FAILED( hRet = lpDSBSound->QueryInterface( IID_IDirectSoundBuffer8, ( void** )&lpDSBOutput ) ) )	{		SAFE_RELEASE( lpDSBSound ) ;		fclose ( pFile ) ;		return ( hRet  ) ;		}	SAFE_RELEASE( lpDSBSound ) ;	if ( FAILED( hRet = lpDSBOutput->Lock( 0, Info.dwDataSize, ( void** )&pData1, &dwSize1,															   ( void** )&pData2, &dwSize2, 0 ) ) )	{		SAFE_RELEASE( lpDSBOutput ) ;		fclose ( pFile ) ;		return ( hRet  ) ;		}	fread( pData1, dwSize1, 1, pFile ) ;	if ( NULL != pData2 )	{		fread( pData2, dwSize2, 1, pFile ) ;	}	lpDSBOutput->Unlock( pData1, dwSize1, pData2, dwSize2 ) ;	return ( S_OK ) ;}


In the SDK samples, MMIO is used to read the format tag. If it's PCM then a WAVEFORMATEX structure is just loaded right from the file. If not, then usually means that the file contains added comments of some sort. The next WORD or format chunk size tells the size of this additional data (in bytes). So I believe the only reason why MMIO is used is because of the support for RIFF type files.

Going of this, I believe I could split the WAVEINFO structure up into two separate structures. The first would contain everything to wFormatTag. Then I check if wFormatTag is equal to WAVE_FORMAT_PCM. It so, I just read in a WAVEFORMATEX structure, else I use the wFormatChunkSize to tell how large the extra section is. I just skip that partt in the file and then proceeed wti hloading the WAVEFORMATEX. The rest of the data should be the same. I haven't tested this out ye, but I'm going to.

I think that the WAV file format is a little more then what I want with the added commenting sections or extra space. I also need to learn how to stream an audio file for music. I don't think that WAV files would be good for this, however, MP3s or something of that sort would. I'm not to sure if MP3 would be any easier then a WAV file to process, but I can at least look into it.

Thanks for the reply!
Take back the internet with the most awsome browser around, FireFox
Ever heard of OpenAL?? It does it all for you man, and supports DirectSound3D under the covers freeing you up from all of that.

Oh and it's free.

hth,
Learn about game programming!Games Programming in C++: Start to Finish

This topic is closed to new replies.

Advertisement