C++ Xbox360 Application XAudio2 playing A xma sound

192 Views Asked by At

I am trying to play a sound through the xbox 360 application using the xbox development kit sdk library XAudio2

I have found a few tutorials and read the Xbox XDK help guide on how to play an audio wav file through the PC, I am trying to play a ".xma" file through the xbox 360

so far the code that works is

IXAudio2* pXAudio2 = nullptr;
if (SUCCEEDED( XAudio2Create( &pXAudio2, 0,XboxThread5 ) ) )
{
  
  IXAudio2MasteringVoice* pXMaster = nullptr;
   pXAudio2->CreateMasteringVoice(&pXMaster,XAUDIO2_DEFAULT_CHANNELS,XAUDIO2_DEFAULT_SAMPLERATE,0,0,NULL);
   WAVEFORMATEXTENSIBLE wfx = { 0 };
    XAUDIO2_BUFFER buffer = { 0 };
    char* strFileName = "HDD:\\s1.xma";
}

when I get to

pXAudio2->CreateSourceVoice( &pSourceVoice, (WAVEFORMATEX*)&wfx,0, XAUDIO2_DEFAULT_FREQ_RATIO, NULL, NULL, NULL );

the xbox crashes

The Syntax for CreateSourceVoice is

C++  

 HRESULT CreateSourceVoice(
         IXAudio2SourceVoice **ppSourceVoice,
         const WAVEFORMATEX *pSourceFormat,
         UINT32 Flags = 0,
         float MaxFrequencyRatio = XAUDIO2_DEFAULT_FREQ_RATIO,
         IXAudio2VoiceCallback *pCallback = NULL,
         const XAUDIO2_VOICE_SENDS *pSendList = NULL,
         const XAUDIO2_EFFECT_CHAIN *pEffectChain = NULL
)
 

the xbox development kit provides a brief tutorial on doing this on PC to WAV files..but does not seem to work on xbox

here is another link to a similar tutorial https://blog.katastros.com/a?ID=00700-419e2519-52d7-45c5-91f6-776778eb3eda

#ifdef _XBOX //Big-Endian
#define fourccRIFF 'RIFF'
#define fourccDATA 'data'
#define fourccFMT 'fmt '
#define fourccWAVE 'WAVE'
#define fourccXWMA 'XWMA'
#define fourccDPDS 'dpds'
#endif

#ifndef _XBOX //Little-Endian
#define fourccRIFF 'FFIR'
#define fourccDATA 'atad'
#define fourccFMT ' tmf'
#define fourccWAVE 'EVAW'
#define fourccXWMA 'AMWX'
#define fourccDPDS 'sdpd'
#endif
HRESULT FindChunk(HANDLE hFile, DWORD fourcc, DWORD & dwChunkSize, DWORD & dwChunkDataPosition)
{
    HRESULT hr = S_OK;
    if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, 0, NULL, FILE_BEGIN ) )
        return HRESULT_FROM_WIN32( GetLastError() );

    DWORD dwChunkType;
    DWORD dwChunkDataSize;
    DWORD dwRIFFDataSize = 0;
    DWORD dwFileType;
    DWORD bytesRead = 0;
    DWORD dwOffset = 0;

    while (hr == S_OK)
    {
        DWORD dwRead;
        if( 0 == ReadFile( hFile, &dwChunkType, sizeof(DWORD), &dwRead, NULL ) )
            hr = HRESULT_FROM_WIN32( GetLastError() );

        if( 0 == ReadFile( hFile, &dwChunkDataSize, sizeof(DWORD), &dwRead, NULL ) )
            hr = HRESULT_FROM_WIN32( GetLastError() );

        switch (dwChunkType)
        {
        case fourccRIFF:
            dwRIFFDataSize = dwChunkDataSize;
            dwChunkDataSize = 4;
            if( 0 == ReadFile( hFile, &dwFileType, sizeof(DWORD), &dwRead, NULL ) )
                hr = HRESULT_FROM_WIN32( GetLastError() );
            break;

        default:
            if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, dwChunkDataSize, NULL, FILE_CURRENT ) )
            return HRESULT_FROM_WIN32( GetLastError() );            
        }

        dwOffset += sizeof(DWORD) * 2;
        
        if (dwChunkType == fourcc)
        {
            dwChunkSize = dwChunkDataSize;
            dwChunkDataPosition = dwOffset;
            return S_OK;
        }

        dwOffset += dwChunkDataSize;
        
        if (bytesRead >= dwRIFFDataSize) return S_FALSE;

    }

    
    return S_OK;
    
}

To read data in a chunk after it has been located.

Once a desired chunk is found, its data can be read by adjusting the file pointer to the beginning of the data section of the chunk. A function to read the data from a chunk once it is found might look like this.

HRESULT ReadChunkData(HANDLE hFile, void * buffer, DWORD buffersize, DWORD bufferoffset)
{
    HRESULT hr = S_OK;
    if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, bufferoffset, NULL, FILE_BEGIN ) )
        return HRESULT_FROM_WIN32( GetLastError() );
    DWORD dwRead;
    if( 0 == ReadFile( hFile, buffer, buffersize, &dwRead, NULL ) )
        hr = HRESULT_FROM_WIN32( GetLastError() );
    return hr;
}

1

There are 1 best solutions below

0
Chuck Walbourn On

The Xbox 360 Developer Program is and was confidential, so I can't comment much in this forum.

XAudio2 only supports XMA2 on Xbox 360, Xbox One, and Xbox Series X|S. XMA2 packages up the header as a WAVEFORMATEX-based format--which was not the case for XMA. See the confidential samples for the Xbox 360 XDK for details.

For robust WAV format reading, take a look at DirectX Tool Kit for Audio.

IIRC, the audio files for Xbox 360 sometimes contained big-endian headers, but the audio data is the same for both Xbox 360 and Xbox One+.