Jump to content
  • Advertisement
Sign in to follow this  
sakky

Know any good audio formats?

This topic is 4725 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 load
WAVEFORMATEX wfx;
File.Open(...);
Zero( &wfx );

// Prepare wav file reading
HMMIO 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 file
MMIOINFO 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 sound
DSBUFFERDESC 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 in
if( !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();
}




Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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,

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!