반응형

 

출처 : https://www.autohotkey.com/boards/viewtopic.php?f=83&t=130425

 

#DllLoad XAudio2_9

PlayWavConcurrent(wavFileName) {
    static obj := initialize()

    initialize() {
        DllCall("XAudio2_9\XAudio2Create", "Ptr*", IXAudio2 := ComValue(13, 0), "Uint", 0, "Uint", 1)
        ComCall(7, IXAudio2, "Ptr*", &IXAudio2MasteringVoice := 0, "Uint", 0, "Uint", 0, "Uint", 0, "Ptr", 0, "Ptr", 0, "Int", 6) ;CreateMasteringVoice
        return { IXAudio2: IXAudio2, someMap: Map() }
    }

    ;freeing is unnecessary, but..
    XAUDIO2_VOICE_STATE := Buffer(A_PtrSize * 2 + 0x8)
    keys_to_delete := []
    for IXAudio2SourceVoice in obj.someMap {
        ComCall(25, IXAudio2SourceVoice, "Ptr", XAUDIO2_VOICE_STATE, "Uint", 0, "Int") ;GetState
        if (!NumGet(XAUDIO2_VOICE_STATE, A_PtrSize, "Uint")) { ;BuffersQueued (includes the one that is being processed)
            keys_to_delete.Push(IXAudio2SourceVoice)
        }
    }
    for IXAudio2SourceVoice in keys_to_delete {
        ComCall(20, IXAudio2SourceVoice, "Uint", 0, "Uint", 0) ;Stop
        ComCall(18, IXAudio2SourceVoice, "Int") ;void DestroyVoice
        obj.someMap.Delete(IXAudio2SourceVoice)
    }

    waveFile := FileRead(wavFileName, "RAW")

    root_tag_to_offset := get_tag_to_offset_map(0, waveFile.Size)
    idk_tag_to_offset := get_tag_to_offset_map(root_tag_to_offset["RIFF"].ofs + 0xc, waveFile.Size)

    WAVEFORMAT_ofs := idk_tag_to_offset["fmt "].ofs + 0x8

    data_ofs := idk_tag_to_offset["data"].ofs + 0x8
    data_size := idk_tag_to_offset["data"].size

    get_tag_to_offset_map(i, end) {
        tag_to_offset := Map()
        while (i < end) {
            tag := StrGet(waveFile.Ptr + i, 4, "UTF-8") ;RIFFChunk::tag
            size := NumGet(waveFile, i + 0x4, "Uint") ;RIFFChunk::size
            tag_to_offset[tag] := { ofs: i, size: size }
            i += size + 0x8
        }
        return tag_to_offset
    }

    ComCall(5, obj.IXAudio2, "Ptr*", &IXAudio2SourceVoice := 0, "Ptr", waveFile.Ptr + WAVEFORMAT_ofs, "int", 0, "float", 2.0, "Ptr", 0, "Ptr", 0, "Ptr", 0) ;CreateSourceVoice

    XAUDIO2_BUFFER := Buffer(A_PtrSize * 2 + 0x1c, 0)
    NumPut("Uint", 0x0040, XAUDIO2_BUFFER, 0x0) ;Flags=XAUDIO2_END_OF_STREAM
    NumPut("Uint", data_size, XAUDIO2_BUFFER, 0x4) ;AudioBytes
    NumPut("Ptr", waveFile.Ptr + data_ofs, XAUDIO2_BUFFER, 0x8) ;pAudioData

    ComCall(21, IXAudio2SourceVoice, "Ptr", XAUDIO2_BUFFER, "Ptr", 0) ;SubmitSourceBuffer
    ComCall(19, IXAudio2SourceVoice, "Uint", 0, "Uint", 0) ;Start

    obj.someMap[IXAudio2SourceVoice] := waveFile
}

f1:: {
    PlayWavConcurrent("C:\Path\To\Your\File.wav")
}
반응형

+ Recent posts