mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-04 15:46:51 -05:00
Got audio rendering working.
This commit is contained in:
parent
89a72c6f33
commit
2921e23bca
@ -10,6 +10,7 @@ type BitStream struct {
|
||||
bitCount int
|
||||
}
|
||||
|
||||
// CreateBitStream creates a new BitStream
|
||||
func CreateBitStream(newData []byte) *BitStream {
|
||||
result := &BitStream{
|
||||
data: newData,
|
||||
@ -20,6 +21,7 @@ func CreateBitStream(newData []byte) *BitStream {
|
||||
return result
|
||||
}
|
||||
|
||||
// ReadBits reads the specified number of bits and returns the value
|
||||
func (v *BitStream) ReadBits(bitCount int) int {
|
||||
if bitCount > 16 {
|
||||
log.Panic("Maximum BitCount is 16")
|
||||
@ -32,6 +34,7 @@ func (v *BitStream) ReadBits(bitCount int) int {
|
||||
return result
|
||||
}
|
||||
|
||||
// PeekByte returns the current byte without adjusting the position
|
||||
func (v *BitStream) PeekByte() int {
|
||||
if !v.EnsureBits(8) {
|
||||
return -1
|
||||
@ -39,6 +42,7 @@ func (v *BitStream) PeekByte() int {
|
||||
return v.current & 0xff
|
||||
}
|
||||
|
||||
// EnsureBits ensures that the specified number of bits are available
|
||||
func (v *BitStream) EnsureBits(bitCount int) bool {
|
||||
if bitCount <= v.bitCount {
|
||||
return true
|
||||
@ -53,6 +57,7 @@ func (v *BitStream) EnsureBits(bitCount int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// WasteBits dry-reads the specified number of bits
|
||||
func (v *BitStream) WasteBits(bitCount int) {
|
||||
v.current >>= bitCount
|
||||
v.bitCount -= bitCount
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
)
|
||||
|
||||
// SceneInterface defines the function necessary for scene management
|
||||
type SceneInterface interface {
|
||||
Load()
|
||||
Unload()
|
||||
|
@ -1,5 +1,11 @@
|
||||
package Common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
// StreamReader allows you to read data from a byte array in various formats
|
||||
type StreamReader struct {
|
||||
data []byte
|
||||
@ -40,6 +46,14 @@ func (v *StreamReader) GetWord() uint16 {
|
||||
return result
|
||||
}
|
||||
|
||||
// GetSWord returns a int16 word from the stream
|
||||
func (v *StreamReader) GetSWord() int16 {
|
||||
var result int16
|
||||
binary.Read(bytes.NewReader([]byte{v.data[v.position], v.data[v.position+1]}), binary.LittleEndian, &result)
|
||||
v.position += 2
|
||||
return result
|
||||
}
|
||||
|
||||
// GetDword returns a uint32 dword from the stream
|
||||
func (v *StreamReader) GetDword() uint32 {
|
||||
result := uint32(v.data[v.position])
|
||||
@ -49,3 +63,22 @@ func (v *StreamReader) GetDword() uint32 {
|
||||
v.position += 4
|
||||
return result
|
||||
}
|
||||
|
||||
// ReadByte implements io.ByteReader
|
||||
func (v *StreamReader) ReadByte() (byte, error) {
|
||||
return v.GetByte(), nil
|
||||
}
|
||||
|
||||
// Read implements io.Reader
|
||||
func (v *StreamReader) Read(p []byte) (n int, err error) {
|
||||
streamLength := v.GetSize()
|
||||
for i := 0; ; i++ {
|
||||
if v.GetPosition() >= streamLength {
|
||||
return i, io.EOF
|
||||
}
|
||||
if i >= len(p) {
|
||||
return i, nil
|
||||
}
|
||||
p[i] = v.GetByte()
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,12 @@ func (v *StreamWriter) PushWord(val uint16) {
|
||||
v.data = append(v.data, byte((val>>8)&0xFF))
|
||||
}
|
||||
|
||||
// PushSWord writes a int16 word to the stream
|
||||
func (v *StreamWriter) PushSWord(val int16) {
|
||||
v.data = append(v.data, byte(val&0xFF))
|
||||
v.data = append(v.data, byte((val>>8)&0xFF))
|
||||
}
|
||||
|
||||
// PushDword writes a uint32 dword to the stream
|
||||
func (v *StreamWriter) PushDword(val uint32) {
|
||||
v.data = append(v.data, byte(val&0xFF))
|
||||
@ -32,6 +38,7 @@ func (v *StreamWriter) PushDword(val uint32) {
|
||||
v.data = append(v.data, byte((val>>24)&0xFF))
|
||||
}
|
||||
|
||||
// GetBytes returns the the byte slice of the underlying data
|
||||
func (v *StreamWriter) GetBytes() []byte {
|
||||
return v.data
|
||||
}
|
||||
|
@ -30,7 +30,6 @@
|
||||
package Compression
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
|
||||
"github.com/essial/OpenDiablo2/Common"
|
||||
@ -345,7 +344,7 @@ func HuffmanDecompress(data []byte) []byte {
|
||||
tail := buildList(sPrime[comptype])
|
||||
head := buildTree(tail)
|
||||
|
||||
var outputstream bytes.Buffer
|
||||
outputstream := Common.CreateStreamWriter()
|
||||
bitstream := Common.CreateBitStream(data[1:])
|
||||
var decoded int
|
||||
for true {
|
||||
@ -356,11 +355,11 @@ func HuffmanDecompress(data []byte) []byte {
|
||||
break
|
||||
case 257:
|
||||
newvalue := bitstream.ReadBits(8)
|
||||
outputstream.WriteByte(byte(newvalue))
|
||||
outputstream.PushByte(byte(newvalue))
|
||||
tail = insertNode(tail, newvalue)
|
||||
break
|
||||
default:
|
||||
outputstream.WriteByte(byte(decoded))
|
||||
outputstream.PushByte(byte(decoded))
|
||||
break
|
||||
}
|
||||
if decoded == 256 {
|
||||
@ -368,5 +367,5 @@ func HuffmanDecompress(data []byte) []byte {
|
||||
}
|
||||
}
|
||||
|
||||
return outputstream.Bytes()
|
||||
return outputstream.GetBytes()
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
package Compression
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"github.com/essial/OpenDiablo2/Common"
|
||||
)
|
||||
|
||||
var sLookup = []int{
|
||||
@ -33,25 +30,21 @@ func WavDecompress(data []byte, channelCount int) []byte {
|
||||
Array1 := []int{0x2c, 0x2c}
|
||||
Array2 := make([]int, channelCount)
|
||||
|
||||
input := bytes.NewReader(data)
|
||||
var output bytes.Buffer
|
||||
outputWriter := bufio.NewWriter(&output)
|
||||
input.ReadByte()
|
||||
input := Common.CreateStreamReader(data)
|
||||
output := Common.CreateStreamWriter()
|
||||
input.GetByte()
|
||||
|
||||
shift, _ := input.ReadByte()
|
||||
shift := input.GetByte()
|
||||
|
||||
for i := 0; i < channelCount; i++ {
|
||||
temp := int16(0)
|
||||
binary.Read(input, binary.LittleEndian, &temp)
|
||||
temp := input.GetSWord()
|
||||
Array2[i] = int(temp)
|
||||
binary.Write(outputWriter, binary.LittleEndian, &temp)
|
||||
output.PushSWord(temp)
|
||||
}
|
||||
|
||||
channel := channelCount - 1
|
||||
pos, _ := input.Seek(0, io.SeekCurrent)
|
||||
input.Seek(pos, io.SeekStart)
|
||||
for pos < int64(input.Len()) {
|
||||
value, _ := input.ReadByte()
|
||||
for input.GetPosition() < input.GetSize() {
|
||||
value := input.GetByte()
|
||||
|
||||
if channelCount == 2 {
|
||||
channel = 1 - channel
|
||||
@ -63,8 +56,7 @@ func WavDecompress(data []byte, channelCount int) []byte {
|
||||
if Array1[channel] != 0 {
|
||||
Array1[channel]--
|
||||
}
|
||||
d := int16(Array2[channel])
|
||||
binary.Write(outputWriter, binary.LittleEndian, &d)
|
||||
output.PushSWord(int16(Array2[channel]))
|
||||
break
|
||||
case 1:
|
||||
Array1[channel] += 8
|
||||
@ -123,9 +115,7 @@ func WavDecompress(data []byte, channelCount int) []byte {
|
||||
}
|
||||
}
|
||||
Array2[channel] = temp3
|
||||
d := int16(temp3)
|
||||
binary.Write(outputWriter, binary.LittleEndian, &d)
|
||||
|
||||
output.PushSWord(int16(temp3))
|
||||
Array1[channel] += sLookup2[value&0x1f]
|
||||
|
||||
if Array1[channel] < 0 {
|
||||
@ -137,5 +127,5 @@ func WavDecompress(data []byte, channelCount int) []byte {
|
||||
}
|
||||
}
|
||||
}
|
||||
return output.Bytes()
|
||||
return output.GetBytes()
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func CreateEngine() *Engine {
|
||||
result.mapMpqFiles()
|
||||
result.loadPalettes()
|
||||
result.loadSoundEntries()
|
||||
audioContext, err := audio.NewContext(48000)
|
||||
audioContext, err := audio.NewContext(22050)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -248,15 +248,13 @@ func (v *Engine) PlayBGM(song string) {
|
||||
v.bgmAudio.Close()
|
||||
}
|
||||
audioData := v.GetFile(song)
|
||||
//audioData2, _ := ioutil.ReadFile(`C:\Users\lunat\Desktop\D2\Extracted\data\global\music\introedit.wav`)
|
||||
//log.Printf("%d, %d", len(audioData), len(audioData2))
|
||||
d, err := wav.Decode(v.audioContext, audio.BytesReadSeekCloser(audioData))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
//s := audio.NewInfiniteLoop(d, int64(len(audioData)))
|
||||
s := audio.NewInfiniteLoop(d, int64(len(audioData)))
|
||||
|
||||
v.bgmAudio, err = audio.NewPlayer(v.audioContext, d)
|
||||
v.bgmAudio, err = audio.NewPlayer(v.audioContext, s)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ func decompressMulti(data []byte, expectedLength uint32) []byte {
|
||||
panic("pk + mpqwav decompression not supported")
|
||||
case 0x81:
|
||||
sinput := Compression.HuffmanDecompress(data[1:])
|
||||
sinput = Compression.WavDecompress(sinput, 1)
|
||||
sinput = Compression.WavDecompress(sinput, 2)
|
||||
tmp := make([]byte, len(sinput))
|
||||
copy(tmp, sinput)
|
||||
return tmp
|
||||
|
19
README.md
19
README.md
@ -35,25 +35,6 @@ The following extensions are recommended for working with this project:
|
||||
* ms-vscode.go
|
||||
* defaltd.go-coverage-viewer
|
||||
|
||||
For the Go extension, it is recommended you add the following to settings.json:
|
||||
```json
|
||||
"go.languageServerExperimentalFeatures": {
|
||||
"format": true,
|
||||
"autoComplete": true,
|
||||
"rename": true,
|
||||
"goToDefinition": true,
|
||||
"hover": true,
|
||||
"signatureHelp": true,
|
||||
"goToTypeDefinition": true,
|
||||
"goToImplementation": true,
|
||||
"documentSymbols": true,
|
||||
"workspaceSymbols": true,
|
||||
"findReferences": true,
|
||||
"diagnostics": true,
|
||||
"documentLink": true
|
||||
},
|
||||
```
|
||||
|
||||
You can get to it by going to settings <kbd>Ctrl+,</kbd>, expanding `Extensions` and selecting `Go configuration`,
|
||||
then clicking on `Edit in settings.json`. Just paste that section where appropriate.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user