ifndef                  _WAV_ASM
_WAV_ASM                equ     1

; ------------------------------------------------------
; Structures
WAV                     struct
Datas                   dword   ?
_Size                   dword   ?
Base_Freq               real4   ?
Looping                 dword   ?
WAV                     ends

; ------------------------------------------------------
; Variables
Wav_Conversion_Table    dd      offset _8Bits_Mono
                        dd      offset _8Bits_Stereo
                        dd      offset _16Bits_Mono
                        dd      offset _16Bits_Stereo

Wav_Mul_Size_Table      db      3, 2, 2, 1
Wav_Shift_Size_Table    db      0, 1, 1, 2

; ------------------------------------------------------
; Includes
                        include Files.asm

;; ------------------------------------------------------
;; Name: Load_WAV
;; Desc: Load a 8 or 16 bits WAV file into memory
Load_WAV                proc    uses ebx esi edi WAV_FName:dword, WAV_Struct:dword, Base_Freq:real4, Looping:dword
                        local   WAV_Buffer:dword
                        local   FSize:dword
                        local   Convert_Idx:dword
                        local   Fmt_Len:dword

                        mov     esi, WAV_Struct
                        mov     [esi + WAV.Datas], NULL
                        mov     [esi + WAV.Base_Freq], CMEM(Base_Freq)
                        mov     [esi + WAV.Looping], CMEM(Looping)

                        ; Load texture into memory
                        invoke  Load_File, WAV_FName, addr FSize
                        test    eax, eax
                        jz      Err_WAV_Load
                        mov     WAV_Buffer, eax
                        add     FSize, eax

                        ; Decode the WAV file
                        mov     ebx, eax
                        cmp     dword ptr [ebx], "FFIR"
                        jne     Err_WAV_Format
                        add     ebx, 8
                        cmp     dword ptr [ebx], "EVAW"
                        jne     Err_WAV_Format
                        add     ebx, 4
                        cmp     dword ptr [ebx], " tmf"
                        jne     Err_WAV_Format
                        add     ebx, 4
                        mov     eax, [ebx]
                        mov     Fmt_Len, eax
                        add     ebx, 4
                        mov     edi, ebx
                        cmp     word ptr [ebx], WAVE_FORMAT_PCM
                        jne     Err_WAV_Format
                        add     ebx, 2
                        mov     ax, word ptr [ebx]
                        xor     ecx, ecx
                        .if     ax == 1 || ax == 2              ; Mono or stereo only
                                .if     ax == 2
                                        inc     ecx
                                .endif
                                mov     Convert_Idx, ecx
                                add     ebx, 2 + 4 + 4 + 2
                                mov     ax, word ptr [ebx]
                                .if     ax == 8 || ax == 16
                                        .if     ax == 16
                                                or      Convert_Idx, 2
                                        .endif
                                        ; Convert the file into stereo/16 bits/floating points
                                        mov     ebx, edi
                                        add     ebx, Fmt_Len
Search_DataChunk:                       .if     ebx >= FSize 
                                                jmp     Err_WAV_Format
                                        .endif
                                        cmp     dword ptr [ebx], "atad"
                                        je      Extra_Header
                                        add     ebx, 4
                                        add     ebx, [ebx]
                                        add     ebx, 4
                                        jmp     Search_DataChunk
Extra_Header:                           add     ebx, 4
                                        mov     eax, [ebx]
                                        mov     edi, eax
                                        mov     ecx, Convert_Idx
                                        mov     cl, [Wav_Mul_Size_Table + ecx]
                                        shl     eax, cl
                                        add     ebx, 4
                                        mov     eax, ALLOCMEM(eax)
                                        test    eax, eax
                                        jz      Err_WAV_Format
                                        mov     [esi + WAV.Datas], eax
                                        mov     edx, Convert_Idx
                                        mov     cl, [Wav_Shift_Size_Table + edx]
                                        mov     edx, edi
                                        shr     edx, cl                         ; Shift the size
                                        mov     [esi + WAV._Size], edx
                                        mov     ecx, edx
                                        mov     esi, ebx
                                        mov     edi, eax
                                        mov     eax, Convert_Idx
                                        mov     eax, [Wav_Conversion_Table + eax * 4]
                                        call    eax
                                        FREEMEM WAV_Buffer
                                        mov     eax, TRUE                       ; Loaded
                                        ret
                                .endif
                        .endif
Err_WAV_Format:         FREEMEM WAV_Buffer
Err_WAV_Load:           xor     eax, eax                                ; Not loaded
                        ret
Load_WAV                endp

; ------------------------------------------------------
; Name: 
; Desc: Various conversion routines from integers to floating points
_8Bits_Mono:            movsx   eax, byte ptr [esi]
                        inc     esi
                        fld     INT2FLT(eax)
                        fdiv    CFLT(127.0)
                        fst     dword ptr [edi]
                        add     edi, 4
                        fstp    dword ptr [edi]
                        add     edi, 4
                        loop    _8Bits_Mono
                        ret

_8Bits_Stereo:          movsx   eax, byte ptr [esi]
                        inc     esi
                        fld     INT2FLT(eax)
                        fdiv    CFLT(127.0)
                        fstp    dword ptr [edi]
                        add     edi, 4
                        movsx   eax, byte ptr [esi]
                        inc     esi
                        fld     INT2FLT(eax)
                        fdiv    CFLT(127.0)
                        fstp    dword ptr [edi]
                        add     edi, 4
                        loop    _8Bits_Stereo
                        ret

_16Bits_Mono:           movsx   eax, word ptr [esi]
                        add     esi, 2
                        fld     INT2FLT(eax)
                        fdiv    CFLT(32767.0)
                        fst     dword ptr [edi]
                        add     edi, 4
                        fstp    dword ptr [edi]
                        add     edi, 4
                        loop    _16Bits_Mono
                        ret

_16Bits_Stereo:         movsx   eax, word ptr [esi]
                        add     esi, 2
                        fld     INT2FLT(eax)
                        fdiv    CFLT(32767.0)
                        fstp    dword ptr [edi]
                        add     edi, 4
                        movsx   eax, word ptr [esi]
                        add     esi, 2
                        fld     INT2FLT(eax)
                        fdiv    CFLT(32767.0)
                        fstp    dword ptr [edi]
                        add     edi, 4
                        loop    _16Bits_Stereo
                        ret

; ------------------------------------------------------
; Name: Unload_WAV
; Desc: Free an allocated WAV sound file
Unload_WAV              proc    WAV_Struct:dword
                        mov     esi, WAV_Struct
                        test    esi, esi
                        jz      @F
                        mov     eax, [esi + WAV.Datas]
                        test    eax, eax
                        jz      @F
                        FREEMEM eax
@@:                     ret
Unload_WAV              endp

endif
