@@ -19,91 +19,103 @@ var command = []string{"custom"}
1919var rsgainSemaphore chan int
2020
2121func main () {
22- albumMode := flag .Bool ("a" , false , "Calculate album gain and peak." )
23- skipExisting := flag .Bool ("S" , false , "Don't scan files with existing ReplayGain information." )
24- tagMode := flag .String ("s" , "s" , "Tagmode:\n s: scan only\n i: write tags\n d: delete tags" )
25- targetLoudness := flag .Int ("l" , - 18 , "Use n LUFS as target loudness (-30 ≤ n ≤ -5), default: -18" )
26- clipMode := flag .String ("c" , "n" , "n: no clipping protection (default),\n p: clipping protection enabled for positive gain values only,\n a: Use max peak level n dB for clipping protection" )
27- quiet := flag .Bool ("q" , false , "(rsgain) Don't print scanning status messages." )
28- rsgainLimit := flag .Int ("r" , 100 , "Limit, how many rsgain instances can run at a time." )
22+ albumMode := * flag .Bool ("a" , false , "Calculate album gain and peak." )
23+ skipExisting := * flag .Bool ("S" , false , "Don't scan files with existing ReplayGain information." )
24+ tagMode := * flag .String ("s" , "s" , "Tagmode:\n s: scan only\n i: write tags\n d: delete tags" )
25+ targetLoudness := * flag .Int ("l" , - 18 , "Use n LUFS as target loudness (-30 ≤ n ≤ -5), default: -18" )
26+ clipMode := * flag .String ("c" , "n" , "n: no clipping protection (default),\n p: clipping protection enabled for positive gain values only,\n a: Use max peak level n dB for clipping protection" )
27+ quiet := * flag .Bool ("q" , false , "(rsgain) Don't print scanning status messages." )
28+ rsgainLimit := * flag .Int ("r" , 100 , "Limit, how many rsgain instances can run at a time." )
2929 flag .Parse ()
3030
3131 libraryRoot := flag .Arg (0 )
3232
3333 // build the rsgain custom command and check values
3434
35- if * albumMode {
35+ if albumMode {
3636 command = append (command , "-a" )
3737 }
3838
39- if * skipExisting {
39+ if skipExisting {
4040 command = append (command , "-S" )
4141 }
4242
43- if ! slices .Contains ([]string {"s" , "d" , "i" }, * tagMode ) {
44- fmt .Printf ("Invalid clip mode : %s" , * tagMode )
43+ if ! slices .Contains ([]string {"s" , "d" , "i" }, tagMode ) {
44+ fmt .Printf ("Invalid tagmode : %s" , tagMode )
4545 os .Exit (2 )
4646 }
47- command = append (command , "-s" , * tagMode )
47+ command = append (command , "-s" , tagMode )
4848
49- if ! (- 30 <= * targetLoudness && * targetLoudness <= - 5 ) {
49+ if ! (- 30 <= targetLoudness && targetLoudness <= - 5 ) {
5050 fmt .Println ("Target loudness n needs to be -30 ≤ n ≤ -5" )
5151 os .Exit (2 )
5252 }
53- command = append (command , "-l" , strconv .Itoa (* targetLoudness ))
53+ command = append (command , "-l" , strconv .Itoa (targetLoudness ))
5454
55- if ! slices .Contains ([]string {"n" , "p" , "a" }, * clipMode ) {
56- fmt .Printf ("Invalid clip mode: %s" , * clipMode )
55+ if ! slices .Contains ([]string {"n" , "p" , "a" }, clipMode ) {
56+ fmt .Printf ("Invalid clip mode: %s" , clipMode )
5757 os .Exit (2 )
5858 }
59- command = append (command , "-c" , * clipMode )
59+ command = append (command , "-c" , clipMode )
6060
6161 if libraryRoot == "" {
6262 fmt .Println ("No library path specified." )
6363 os .Exit (2 )
6464 }
6565
66- if * quiet {
66+ if quiet {
6767 command = append (command , "-q" )
6868 }
6969
70- rsgainSemaphore = make (chan int , * rsgainLimit )
70+ rsgainSemaphore = make (chan int , rsgainLimit )
7171
7272 /* Used for debugging
7373 ctx, cancel := context.WithCancel(context.Background())
7474 go monitorRsgainProcesses(ctx, 500*time.Millisecond)
7575 */
7676
77- // scan for album folders
78- wg .Add (1 )
79- err := walker (libraryRoot )
77+ // if root is just a file
78+ if isSupportedMusicFile (libraryRoot ) {
79+ err := runRSGain ([]string {libraryRoot }, quiet )
80+ if err != nil {
81+ errLog .Printf ("Something went wrong scanning %s: '%s\n '" , libraryRoot , err )
82+ }
83+ } else { // if we have a folder, scan them with WalkDir
84+ wg .Add (1 )
85+ err := walker (libraryRoot , quiet )
8086
81- if err != nil {
82- errLog .Printf ("Error walking library folder: %s\n " , err )
83- }
87+ if err != nil {
88+ errLog .Printf ("Error walking library folder: %s\n " , err )
89+ }
8490
85- wg .Wait ()
91+ wg .Wait ()
92+ }
8693
8794 /*cancel()*/
8895}
8996
90- func walker (root string ) error {
97+ func walker (root string , isQuiet bool ) error {
9198 defer wg .Done ()
9299 return filepath .WalkDir (root , func (path string , d fs.DirEntry , err error ) error {
93100 if err != nil {
94101 return err
95102 }
96103
97- // skip creating walkers on the initial directory (it would create infinite threads lol)
98- if d .IsDir () && path != root {
99- // when walked into a directory, launch a new walker on that
100- wg .Add (1 )
101- go func () {
102- err := walker (path )
103- if err != nil {
104- errLog .Printf ("Error walking %s: %s\n " , path , err )
105- }
106- }()
104+ if d .IsDir () {
105+ // skip creating walkers on the initial directory (it would create infinite threads lol)
106+ if path != root {
107+ // when walked into a directory, launch a new walker on that
108+ wg .Add (1 )
109+ go func () {
110+ err := walker (path , isQuiet )
111+ if err != nil {
112+ errLog .Printf ("Error walking %s: %s\n " , path , err )
113+ }
114+ }()
115+
116+ // skip the current directory (the newly summoned walker is dealing with it)
117+ return fs .SkipDir
118+ }
107119
108120 // process supported files (separate thread)
109121 wg .Add (1 )
@@ -128,25 +140,35 @@ func walker(root string) error {
128140 rsgainSemaphore <- 0 //add a slot to the semaphore
129141 defer func () { <- rsgainSemaphore }()
130142
131- cmd := exec .Command ("rsgain" , append (command , audioFiles ... )... )
132- err := cmd .Run ()
133-
134- if err != nil {
135- errLog .Printf ("Error calling rsgain on these files: '%v'\n " , audioFiles )
136- errLog .Printf ("Command failed: %s\n Error: %v\n " , cmd .String (), err )
137-
138- }
143+ err = runRSGain (audioFiles , isQuiet )
139144 }
140145 }()
141-
142- // skip the current directory (the newly summoned walker is dealing with it)
143- return fs .SkipDir
144146 }
145147
146- return nil
148+ return err
147149 })
148150}
149151
152+ func runRSGain (audioFiles []string , isQuiet bool ) error {
153+ cmd := exec .Command ("rsgain" , append (command , audioFiles ... )... )
154+
155+ // Stream output to console if set
156+ if ! isQuiet {
157+ cmd .Stdout = os .Stdout
158+ cmd .Stderr = os .Stderr
159+ }
160+
161+ err := cmd .Run ()
162+
163+ if err != nil {
164+ errLog .Printf ("Error calling rsgain on these files: '%v'\n " , audioFiles )
165+ errLog .Printf ("Command failed: %s\n Error: %v\n " , cmd .String (), err )
166+
167+ }
168+
169+ return err
170+ }
171+
150172func isSupportedMusicFile (path string ) bool {
151173 supportedFiles := []string {
152174 ".aiff" , ".flac" , ".flac" ,
0 commit comments