-
Notifications
You must be signed in to change notification settings - Fork 1
/
lpcm_2_wav-lpcm.go
101 lines (86 loc) · 3.45 KB
/
lpcm_2_wav-lpcm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package transcoder
import (
"bufio"
"fmt"
"io"
"os"
"github.com/pablodz/sopro/pkg/audioconfig"
"github.com/pablodz/sopro/pkg/cpuarch"
"github.com/pablodz/sopro/pkg/encoding"
"github.com/pablodz/sopro/pkg/sopro"
"github.com/pablodz/sopro/utils"
)
// PCM to WAV-LPCM transcoder is only adding the WAV header to the PCM data
func lpcm2WavLpcm(in *sopro.In, out *sopro.Out, tr *Transcoder) (err error) {
if tr.Verbose {
// read all the file
sopro.GraphIn(in)
}
// Get the WAV file configuration
channels := out.Config.(audioconfig.WavConfig).Channels
sampleRate := out.Config.(audioconfig.WavConfig).SampleRate
bitsPerSample := out.Config.(audioconfig.WavConfig).BitDepth
tr.InConfigs.Encoding = in.Config.(audioconfig.PcmConfig).Encoding
tr.OutConfigs.Encoding = out.Config.(audioconfig.WavConfig).Encoding
tr.BitDepth = bitsPerSample
if tr.InConfigs.Endianness == cpuarch.NOT_FILLED && tr.OutConfigs.Endianness == cpuarch.NOT_FILLED {
tr.InConfigs.Endianness = cpuarch.LITTLE_ENDIAN // replace with cpuarch.GetEndianess()
tr.OutConfigs.Endianness = cpuarch.LITTLE_ENDIAN
}
tr.Println(
"\n[Format] ", in.Format, "=>", out.Format,
"\n[Encoding] ", encoding.ENCODINGS[in.Config.(audioconfig.PcmConfig).Encoding], "=>", encoding.ENCODINGS[out.Config.(audioconfig.WavConfig).Encoding],
"\n[Channels] ", in.Config.(audioconfig.PcmConfig).Channels, "=>", channels,
"\n[SampleRate] ", in.Config.(audioconfig.PcmConfig).SampleRate, "=>", sampleRate, "Hz",
"\n[BitDepth] ", in.Config.(audioconfig.PcmConfig).BitDepth, "=>", bitsPerSample, "bytes",
"\n[Transcoder][Source][Encoding]", encoding.ENCODINGS[tr.InConfigs.Encoding],
"\n[Transcoder][Target][Encoding]", encoding.ENCODINGS[tr.OutConfigs.Encoding],
"\n[Transcoder][BitDepth] ", tr.BitDepth,
"\n[Transcoder][Endianness] ", cpuarch.ENDIANESSES[cpuarch.GetEndianess()],
)
// Create a buffered reader and writer
in.Reader = bufio.NewReader(in.Data)
out.Writer = bufio.NewWriter(out.Data)
out.Length = 0
headerWavZero := utils.GenerateSpaceForWavHeader()
out.Writer.Write(headerWavZero)
out.Length += 44
// Copy the data from the input file to the output file in chunks
if _, err = TranscodeBytes(in, out, tr); err != nil {
return fmt.Errorf("error converting bytes: %v", err)
}
// Flush the output file
err = out.Writer.Flush()
if err != nil {
return fmt.Errorf("error flushing output file: %v", err)
}
tr.Println("Wrote", out.Length, "bytes to output file")
// Update the file size and data size fields
fileFixer := out.Data.(*os.File)
r, err := fileFixer.Seek(0, io.SeekStart)
if err != nil {
return fmt.Errorf("error seeking file: %v", err)
}
tr.Println("Seeked to:", r)
out.NewConfig(audioconfig.WavConfig{
BitDepth: bitsPerSample,
Channels: channels,
Encoding: tr.OutConfigs.Encoding,
SampleRate: sampleRate,
WaveFormat: audioconfig.WAVE_FORMAT_PCM,
})
headersWav := utils.GenerateWavHeadersWithSize(out.Config.(audioconfig.WavConfig), out.Length)
if tr.Verbose {
audioconfig.PrintWavHeaders(headersWav)
}
n, err := fileFixer.Write(headersWav)
if err != nil {
return fmt.Errorf("error writing file size: %v", err)
}
tr.Println("File size:", fmt.Sprintf("% 02x", out.Length-8), "bytes written:", n)
tr.Println("Data size:", fmt.Sprintf("% 02x", out.Length-44), "bytes written:", n)
if tr.Verbose {
sopro.GraphOut(in, out)
}
return fileFixer.Close()
}