Browse Source

audio: proper RIFF header generation.

At last!

[RIFF][following size][WAVE]fmt[...]...data[data size][padded data].

Also, update example.wav.
Dmitry Chestnykh 14 years ago
parent
commit
05ff9ea76c
3 changed files with 18 additions and 10 deletions
  1. 17 9
      audio.go
  2. BIN
      capgen/example.wav
  3. 1 1
      sounds.go

+ 17 - 9
audio.go

@@ -86,19 +86,27 @@ func NewAudio(digits []byte) *Audio {
 // WriteTo writes captcha audio in WAVE format into the given io.Writer, and
 // WriteTo writes captcha audio in WAVE format into the given io.Writer, and
 // returns the number of bytes written and an error if any.
 // returns the number of bytes written and an error if any.
 func (a *Audio) WriteTo(w io.Writer) (n int64, err os.Error) {
 func (a *Audio) WriteTo(w io.Writer) (n int64, err os.Error) {
+	// Calculate padded length of PCM chunk data.
+	bodyLen := uint32(a.body.Len())
+	paddedBodyLen := bodyLen
+	if bodyLen % 2 != 0 {
+		paddedBodyLen++
+	}
+	totalLen := uint32(len(waveHeader)) - 4 + paddedBodyLen
 	// Header.
 	// Header.
-	nn, err := w.Write(waveHeader)
+	header := make([]byte, len(waveHeader) + 4) // includes 4 bytes for chunk size
+	copy(header, waveHeader)
+	// Put the length of whole RIFF chunk.
+	binary.LittleEndian.PutUint32(header[4:], totalLen)
+	// Put the length of WAVE chunk.
+	binary.LittleEndian.PutUint32(header[len(waveHeader):], bodyLen)
+	// Write header.
+	nn, err := w.Write(header)
 	n = int64(nn)
 	n = int64(nn)
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
-	// Chunk length.
-	err = binary.Write(w, binary.LittleEndian, uint32(a.body.Len()))
-	if err != nil {
-		return
-	}
-	nn += 4
-	// Chunk data.
+	// Write data.
 	n, err = a.body.WriteTo(w)
 	n, err = a.body.WriteTo(w)
 	n += int64(nn)
 	n += int64(nn)
 	if err != nil {
 	if err != nil {
@@ -106,7 +114,7 @@ func (a *Audio) WriteTo(w io.Writer) (n int64, err os.Error) {
 	}
 	}
 	// Pad byte if chunk length is odd.
 	// Pad byte if chunk length is odd.
 	// (As header has even length, we can check if n is odd, not chunk).
 	// (As header has even length, we can check if n is odd, not chunk).
-	if n % 2 != 0 {
+	if bodyLen != paddedBodyLen {
 		w.Write([]byte{0})
 		w.Write([]byte{0})
 		n++
 		n++
 	}
 	}

BIN
capgen/example.wav


+ 1 - 1
sounds.go

@@ -3,7 +3,7 @@ package captcha
 // This file has been generated from .wav files using generate.go.
 // This file has been generated from .wav files using generate.go.
 
 
 var waveHeader = []byte{
 var waveHeader = []byte{
-	0x52, 0x49, 0x46, 0x46, 0xdf, 0x0a, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
+	0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
 	0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
 	0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
 	0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
 	0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
 	0x64, 0x61, 0x74, 0x61,
 	0x64, 0x61, 0x74, 0x61,