Skip to content

Commit 4ffca93

Browse files
committed
Read FLAC TITLE metadata tag
- Scan FLAC data for TITLE metadata tag and use for WAV file name, if present
1 parent 4237824 commit 4ffca93

3 files changed

Lines changed: 55 additions & 10 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Argument | Description
1212

1313
`-` can be used in place of `<file>` to designate standard output as the destination. When piping a FLAC stream, the complete header is included. However, when piping a WAV stream, the header is unfinished until the write operation is complete, meaning you may have to skip the first 44 bytes in order for the receiving application to process the stream in real time.
1414

15-
Without any arguments, the embedded FLAC data will be transcoded into the working directory to a WAV file of the same name as the executable, except with the `.wav` extension. So, command-line usage is only optional and the end user can just execute the application as they would any other application for this default behavior.
15+
Without any arguments, the embedded FLAC data will be transcoded into the working directory to a WAV file of the same name as the executable, or TITLE metadata tag if present within the FLAC, except with the `.wav` extension. So, command-line usage is only optional and the end user can just execute the application as they would any other application for this default behavior.
1616

1717
# Appending a FLAC file to a stand-alone FLACSFX executable, recommended for most users
1818
Download the latest pre-built release for the intended target system:

flacsfx.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ func main() {
103103
// Display stream info and exit
104104
if info {
105105
os.Stdout.WriteString(
106+
"TITLE="+wavName+"\n"+
106107
"codec_name=flac\n"+
107108
"codec_long_name=FLAC (Free Lossless Audio Codec)\n"+
108109
"codec_type=audio\n"+

sa.go

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,59 @@ func init() {
1717
filePath, _ := os.Executable()
1818
filePath, _ = filepath.EvalSymlinks(filePath)
1919

20-
// Name wav file after executable
21-
wavName = strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath))+".wav"
22-
2320
// Slurp file into memory
2421
fileData, _ := os.ReadFile(filePath)
2522

2623
// Determine length of transcoder / start of FLAC data
24+
// Find TITLE tag and use for file name if present
2725
tcSize := int64(1000000)
26+
var titleTagBuilder strings.Builder
2827
for {
2928
if fileData[tcSize-1] == 0x00 &&
30-
fileData[tcSize] == 0x66 &&
31-
fileData[tcSize+1] == 0x4c &&
32-
fileData[tcSize+2] == 0x61 &&
33-
fileData[tcSize+3] == 0x43 &&
34-
fileData[tcSize+4] == 0x00 {
35-
break
29+
fileData[tcSize] == 0x66 &&
30+
fileData[tcSize+1] == 0x4c &&
31+
fileData[tcSize+2] == 0x61 &&
32+
fileData[tcSize+3] == 0x43 &&
33+
fileData[tcSize+4] == 0x00 {
34+
titleTag := tcSize+32
35+
for {
36+
if fileData[titleTag] == 0x00 &&
37+
fileData[titleTag+1] == 0x54 &&
38+
fileData[titleTag+2] == 0x49 &&
39+
fileData[titleTag+3] == 0x54 &&
40+
fileData[titleTag+4] == 0x4C &&
41+
fileData[titleTag+5] == 0x45 &&
42+
fileData[titleTag+6] == 0x3D {
43+
titleTag = titleTag+7
44+
for {
45+
if fileData[titleTag+1] == 0x00 {break}
46+
titleTagBuilder.WriteByte(fileData[titleTag])
47+
titleTag++
48+
}
49+
break
50+
}
51+
if (int(titleTag) == len(fileData)-6) ||
52+
(fileData[titleTag] == 0x00 &&
53+
fileData[titleTag+1] == 0x00 &&
54+
fileData[titleTag+2] == 0x00 &&
55+
fileData[titleTag+3] == 0x00 &&
56+
fileData[titleTag+4] == 0x00 &&
57+
fileData[titleTag+5] == 0x00 &&
58+
fileData[titleTag+6] == 0x00 &&
59+
fileData[titleTag+7] == 0x00 &&
60+
fileData[titleTag+8] == 0x00 &&
61+
fileData[titleTag+9] == 0x00 &&
62+
fileData[titleTag+10] == 0x00 &&
63+
fileData[titleTag+11] == 0x00 &&
64+
fileData[titleTag+12] == 0x00 &&
65+
fileData[titleTag+13] == 0x00 &&
66+
fileData[titleTag+14] == 0x00 &&
67+
fileData[titleTag+15] == 0x00) {
68+
break
69+
}
70+
titleTag++
71+
}
72+
break
3673
}
3774
if int(tcSize) == len(fileData)-6 {
3875
os.Stdout.WriteString("No FLAC data found.")
@@ -41,6 +78,13 @@ func init() {
4178
tcSize++
4279
}
4380

81+
// Name wav file after executable, or title tag if present
82+
if titleTagBuilder.Len() == 0 {
83+
wavName = strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath))+".wav"
84+
} else {
85+
wavName = titleTagBuilder.String()+".wav"
86+
}
87+
4488
// Calculate length of FLAC data
4589
flacSize := int64(len(fileData))-tcSize
4690

0 commit comments

Comments
 (0)