fixes filter on MPT-transition. Add a high quality filter wir anti-aliasing
This commit is contained in:
281
main.go
281
main.go
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -16,6 +17,9 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
//go:embed assets/logo.png
|
||||
var logoData []byte
|
||||
|
||||
// processIR processes a single recorded file and generates IR(s)
|
||||
func processIR(c *cli.Context, sweepData *wav.WAVData, recordedPath, outputPath string) error {
|
||||
// Read recorded WAV file
|
||||
@@ -132,7 +136,7 @@ func processIR(c *cli.Context, sweepData *wav.WAVData, recordedPath, outputPath
|
||||
// Plot IR waveform if requested
|
||||
if c.Bool("plot-ir") {
|
||||
log.Printf("Plotting IR waveform...")
|
||||
err := plot.PlotIR(ir, sampleRate, outputPath)
|
||||
err := plot.PlotIR(ir, sampleRate, outputPath, logoData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to plot IR: %v", err)
|
||||
}
|
||||
@@ -142,12 +146,12 @@ func processIR(c *cli.Context, sweepData *wav.WAVData, recordedPath, outputPath
|
||||
// Generate MPT IR if requested
|
||||
if c.Bool("mpt") {
|
||||
log.Println("Generating minimum phase transform...")
|
||||
// Use the original 96kHz IR for MPT generation
|
||||
// Use the filtered recorded sweep for MPT generation (same as RAW IR)
|
||||
var originalIR []float64
|
||||
if c.Bool("no-phase-correction") {
|
||||
originalIR = convolve.Deconvolve(sweepData.PCMData, recordedData.PCMData)
|
||||
originalIR = convolve.Deconvolve(sweepData.PCMData, recordedFiltered)
|
||||
} else {
|
||||
originalIR = convolve.DeconvolveWithPhaseCorrection(sweepData.PCMData, recordedData.PCMData)
|
||||
originalIR = convolve.DeconvolveWithPhaseCorrection(sweepData.PCMData, recordedFiltered)
|
||||
}
|
||||
originalIR = convolve.TrimSilence(originalIR, 1e-5)
|
||||
mptIR := convolve.MinimumPhaseTransform(originalIR)
|
||||
@@ -328,12 +332,17 @@ func processCabpack(c *cli.Context, sweepData *wav.WAVData, recordedDir, outputD
|
||||
// cut-slope: default is already 12, so no change needed
|
||||
cutSlope := c.Int("cut-slope")
|
||||
|
||||
// Find all WAV files in the recorded directory, excluding the sweep file
|
||||
// Find all WAV files in the recorded directory, excluding the sweep file and mixes folder
|
||||
mixesDir := filepath.Join(recordedDir, "mixes")
|
||||
var wavFiles []string
|
||||
err := filepath.Walk(recordedDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Skip the mixes folder - files there are processed separately
|
||||
if info.IsDir() && path == mixesDir {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if !info.IsDir() && strings.ToLower(filepath.Ext(path)) == ".wav" {
|
||||
// Exclude the sweep file from processing
|
||||
fileName := filepath.Base(path)
|
||||
@@ -374,6 +383,26 @@ func processCabpack(c *cli.Context, sweepData *wav.WAVData, recordedDir, outputD
|
||||
// Get all format specifications
|
||||
formats := getCabpackFormats()
|
||||
|
||||
// Check which optional files/folders exist
|
||||
selectionListPath := filepath.Join(recordedDir, "selection.txt")
|
||||
ambientListPath := filepath.Join(recordedDir, "ambient.txt")
|
||||
// mixesDir is already defined above in filepath.Walk
|
||||
|
||||
hasSelection := false
|
||||
if _, err := os.Stat(selectionListPath); err == nil {
|
||||
hasSelection = true
|
||||
}
|
||||
|
||||
hasAmbient := false
|
||||
if _, err := os.Stat(ambientListPath); err == nil {
|
||||
hasAmbient = true
|
||||
}
|
||||
|
||||
hasMixes := false
|
||||
if _, err := os.Stat(mixesDir); err == nil {
|
||||
hasMixes = true
|
||||
}
|
||||
|
||||
// Create directory structure for each format
|
||||
for _, format := range formats {
|
||||
formatFolder := formatFolderName(cabpackBase, format)
|
||||
@@ -384,17 +413,13 @@ func processCabpack(c *cli.Context, sweepData *wav.WAVData, recordedDir, outputD
|
||||
return fmt.Errorf("failed to create format folder %s: %v", formatPath, err)
|
||||
}
|
||||
|
||||
// Create subfolders: ambient mics, close mics, mixees, selection
|
||||
subfolders := []string{"ambient mics", "close mics", "mixees", "selection"}
|
||||
for _, subfolder := range subfolders {
|
||||
subfolderPath := filepath.Join(formatPath, subfolder)
|
||||
if err := os.MkdirAll(subfolderPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create subfolder %s: %v", subfolderPath, err)
|
||||
}
|
||||
// Always create "close mics" folder
|
||||
closeMicsPath := filepath.Join(formatPath, "close mics")
|
||||
if err := os.MkdirAll(closeMicsPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create close mics folder: %v", err)
|
||||
}
|
||||
|
||||
// Create RAW and MPT folders inside "close mics"
|
||||
closeMicsPath := filepath.Join(formatPath, "close mics")
|
||||
rawPath := filepath.Join(closeMicsPath, "RAW")
|
||||
mptPath := filepath.Join(closeMicsPath, "MPT")
|
||||
if err := os.MkdirAll(rawPath, 0755); err != nil {
|
||||
@@ -404,26 +429,44 @@ func processCabpack(c *cli.Context, sweepData *wav.WAVData, recordedDir, outputD
|
||||
return fmt.Errorf("failed to create MPT folder: %v", err)
|
||||
}
|
||||
|
||||
// Create RAW and MPT folders inside "selection"
|
||||
selectionPath := filepath.Join(formatPath, "selection")
|
||||
selectionRawPath := filepath.Join(selectionPath, "RAW")
|
||||
selectionMptPath := filepath.Join(selectionPath, "MPT")
|
||||
if err := os.MkdirAll(selectionRawPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create selection RAW folder: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(selectionMptPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create selection MPT folder: %v", err)
|
||||
// Create "selection" folder and subfolders only if selection.txt exists
|
||||
if hasSelection {
|
||||
selectionPath := filepath.Join(formatPath, "selection")
|
||||
if err := os.MkdirAll(selectionPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create selection folder: %v", err)
|
||||
}
|
||||
selectionRawPath := filepath.Join(selectionPath, "RAW")
|
||||
selectionMptPath := filepath.Join(selectionPath, "MPT")
|
||||
if err := os.MkdirAll(selectionRawPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create selection RAW folder: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(selectionMptPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create selection MPT folder: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create RAW and MPT folders inside "ambient mics"
|
||||
ambientPath := filepath.Join(formatPath, "ambient mics")
|
||||
ambientRawPath := filepath.Join(ambientPath, "RAW")
|
||||
ambientMptPath := filepath.Join(ambientPath, "MPT")
|
||||
if err := os.MkdirAll(ambientRawPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create ambient RAW folder: %v", err)
|
||||
// Create "ambient mics" folder and subfolders only if ambient.txt exists
|
||||
if hasAmbient {
|
||||
ambientPath := filepath.Join(formatPath, "ambient mics")
|
||||
if err := os.MkdirAll(ambientPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create ambient mics folder: %v", err)
|
||||
}
|
||||
ambientRawPath := filepath.Join(ambientPath, "RAW")
|
||||
ambientMptPath := filepath.Join(ambientPath, "MPT")
|
||||
if err := os.MkdirAll(ambientRawPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create ambient RAW folder: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(ambientMptPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create ambient MPT folder: %v", err)
|
||||
}
|
||||
}
|
||||
if err := os.MkdirAll(ambientMptPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create ambient MPT folder: %v", err)
|
||||
|
||||
// Create "mixes" folder only if mixes folder exists in recorded directory
|
||||
if hasMixes {
|
||||
mixesPath := filepath.Join(formatPath, "mixes")
|
||||
if err := os.MkdirAll(mixesPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create mixes folder: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,6 +476,15 @@ func processCabpack(c *cli.Context, sweepData *wav.WAVData, recordedDir, outputD
|
||||
return fmt.Errorf("failed to create plots folder: %v", err)
|
||||
}
|
||||
|
||||
// Create mixes subfolder in plots only if mixes folder exists
|
||||
var plotsMixesPath string
|
||||
if hasMixes {
|
||||
plotsMixesPath = filepath.Join(plotsPath, "mixes")
|
||||
if err := os.MkdirAll(plotsMixesPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create plots/mixes folder: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Process each WAV file
|
||||
successCount := 0
|
||||
for i, recordedFile := range wavFiles {
|
||||
@@ -481,7 +533,7 @@ func processCabpack(c *cli.Context, sweepData *wav.WAVData, recordedDir, outputD
|
||||
} else {
|
||||
// Pass path without .png extension - PlotIR will add it
|
||||
plotBasePath := filepath.Join(plotsPath, recordedName)
|
||||
if err := plot.PlotIR(plotIR, plotFormat.SampleRate, plotBasePath+".wav"); err != nil {
|
||||
if err := plot.PlotIR(plotIR, plotFormat.SampleRate, plotBasePath+".wav", logoData); err != nil {
|
||||
log.Printf("ERROR generating plot: %v", err)
|
||||
} else {
|
||||
log.Printf("Plot saved: %s.png", plotBasePath)
|
||||
@@ -499,11 +551,144 @@ func processCabpack(c *cli.Context, sweepData *wav.WAVData, recordedDir, outputD
|
||||
|
||||
// Process selection.txt and ambient.txt files
|
||||
log.Printf("\nProcessing selection and ambient file lists...")
|
||||
if err := processSelectionAndAmbientLists(recordedDir, outputDir, cabpackBase, formats); err != nil {
|
||||
if err := processSelectionAndAmbientLists(recordedDir, outputDir, cabpackBase, formats, hasSelection, hasAmbient); err != nil {
|
||||
log.Printf("Warning: Error processing selection/ambient lists: %v", err)
|
||||
// Don't fail the entire process if this fails
|
||||
}
|
||||
|
||||
// Process mixes folder if it exists
|
||||
if hasMixes {
|
||||
log.Printf("\nProcessing mixes folder...")
|
||||
if err := processMixesFolder(c, mixesDir, outputDir, cabpackBase, formats, plotsMixesPath, fadeMs); err != nil {
|
||||
log.Printf("Warning: Error processing mixes folder: %v", err)
|
||||
// Don't fail the entire process if this fails
|
||||
}
|
||||
} else {
|
||||
log.Printf("Mixes folder not found, skipping mixes processing")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// processMixesFolder processes ready-to-use IR files from the mixes folder
|
||||
func processMixesFolder(c *cli.Context, mixesDir, outputDir, cabpackBase string, formats []formatSpec, plotsMixesPath string, fadeMs float64) error {
|
||||
// Find all WAV files in the mixes directory
|
||||
var mixFiles []string
|
||||
err := filepath.Walk(mixesDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() && strings.ToLower(filepath.Ext(path)) == ".wav" {
|
||||
mixFiles = append(mixFiles, path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to scan mixes directory: %v", err)
|
||||
}
|
||||
|
||||
if len(mixFiles) == 0 {
|
||||
log.Printf("No WAV files found in mixes folder")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Found %d IR file(s) in mixes folder to convert", len(mixFiles))
|
||||
|
||||
// Process each mix file
|
||||
successCount := 0
|
||||
for i, mixFile := range mixFiles {
|
||||
log.Printf("\n[%d/%d] Processing mix IR: %s", i+1, len(mixFiles), filepath.Base(mixFile))
|
||||
|
||||
// Read the IR file (it's already an IR, not a recorded sweep)
|
||||
irData, err := wav.ReadWAVFile(mixFile)
|
||||
if err != nil {
|
||||
log.Printf("ERROR reading %s: %v", mixFile, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Get base name for output files (without extension)
|
||||
mixBase := filepath.Base(mixFile)
|
||||
mixName := strings.TrimSuffix(mixBase, filepath.Ext(mixBase))
|
||||
|
||||
// The IR is already at 96kHz after ReadWAVFile, so we can use it directly
|
||||
ir := irData.PCMData
|
||||
|
||||
// Normalize the IR
|
||||
ir = convolve.Normalize(ir, c.Float64("normalize"))
|
||||
|
||||
// Process each format
|
||||
for _, format := range formats {
|
||||
log.Printf(" Converting to format: %dHz, %d-bit, %.0fms", format.SampleRate, format.BitDepth, format.LengthMs)
|
||||
|
||||
formatFolder := formatFolderName(cabpackBase, format)
|
||||
mixesPath := filepath.Join(outputDir, formatFolder, "mixes")
|
||||
|
||||
// Convert IR to target format
|
||||
convertedIR := make([]float64, len(ir))
|
||||
copy(convertedIR, ir)
|
||||
|
||||
// Resample IR to target sample rate if different from input (96kHz)
|
||||
targetSampleRate := format.SampleRate
|
||||
if targetSampleRate != 96000 {
|
||||
convertedIR = convolve.Resample(convertedIR, 96000, targetSampleRate)
|
||||
}
|
||||
|
||||
// Trim or pad IR to requested length
|
||||
targetSamples := int(float64(targetSampleRate) * format.LengthMs / 1000.0)
|
||||
convertedIR = convolve.TrimOrPad(convertedIR, targetSamples)
|
||||
|
||||
// Apply fade-out
|
||||
fadeSamples := int(float64(targetSampleRate) * fadeMs / 1000.0)
|
||||
if fadeSamples > 0 {
|
||||
convertedIR = convolve.FadeOutLinear(convertedIR, fadeSamples)
|
||||
}
|
||||
|
||||
// Write converted IR
|
||||
outputPath := filepath.Join(mixesPath, mixName+".wav")
|
||||
if err := wav.WriteWAVFileWithOptions(outputPath, convertedIR, format.SampleRate, format.BitDepth); err != nil {
|
||||
log.Printf("ERROR writing converted IR for %s in format %s: %v", mixName, formatFolder, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Generate plot for 96000Hz format (only once per file)
|
||||
plotFormat := formatSpec{96000, 24, 500}
|
||||
plotIR := make([]float64, len(ir))
|
||||
copy(plotIR, ir)
|
||||
plotIR = convolve.Normalize(plotIR, c.Float64("normalize"))
|
||||
|
||||
// Resample to 96kHz if needed (should already be 96kHz)
|
||||
if irData.SampleRate != 96000 {
|
||||
plotIR = convolve.Resample(plotIR, irData.SampleRate, 96000)
|
||||
}
|
||||
|
||||
// Trim or pad for plot format
|
||||
targetSamples := int(float64(96000) * plotFormat.LengthMs / 1000.0)
|
||||
plotIR = convolve.TrimOrPad(plotIR, targetSamples)
|
||||
|
||||
// Apply fade-out
|
||||
fadeSamples := int(float64(96000) * fadeMs / 1000.0)
|
||||
if fadeSamples > 0 {
|
||||
plotIR = convolve.FadeOutLinear(plotIR, fadeSamples)
|
||||
}
|
||||
|
||||
// Generate plot
|
||||
plotBasePath := filepath.Join(plotsMixesPath, mixName)
|
||||
if err := plot.PlotIR(plotIR, plotFormat.SampleRate, plotBasePath+".wav", logoData); err != nil {
|
||||
log.Printf("ERROR generating plot for mix: %v", err)
|
||||
} else {
|
||||
log.Printf("Plot saved: %s.png", plotBasePath)
|
||||
}
|
||||
|
||||
successCount++
|
||||
log.Printf("Successfully processed mix IR: %s", mixBase)
|
||||
}
|
||||
|
||||
log.Printf("\nMixes processing complete: %d/%d files processed successfully", successCount, len(mixFiles))
|
||||
if successCount < len(mixFiles) {
|
||||
return fmt.Errorf("some mix files failed to process (%d/%d succeeded)", successCount, len(mixFiles))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -562,10 +747,10 @@ func moveFile(src, dst string) error {
|
||||
}
|
||||
|
||||
// processSelectionAndAmbientLists processes selection.txt and ambient.txt files
|
||||
func processSelectionAndAmbientLists(recordedDir, outputDir, cabpackBase string, formats []formatSpec) error {
|
||||
func processSelectionAndAmbientLists(recordedDir, outputDir, cabpackBase string, formats []formatSpec, hasSelection, hasAmbient bool) error {
|
||||
// Process selection.txt first (copy files)
|
||||
selectionListPath := filepath.Join(recordedDir, "selection.txt")
|
||||
if _, err := os.Stat(selectionListPath); err == nil {
|
||||
if hasSelection {
|
||||
log.Printf("Processing selection.txt...")
|
||||
selectionFiles, err := readFileList(selectionListPath)
|
||||
if err != nil {
|
||||
@@ -625,7 +810,7 @@ func processSelectionAndAmbientLists(recordedDir, outputDir, cabpackBase string,
|
||||
|
||||
// Process ambient.txt (move files)
|
||||
ambientListPath := filepath.Join(recordedDir, "ambient.txt")
|
||||
if _, err := os.Stat(ambientListPath); err == nil {
|
||||
if hasAmbient {
|
||||
log.Printf("Processing ambient.txt...")
|
||||
ambientFiles, err := readFileList(ambientListPath)
|
||||
if err != nil {
|
||||
@@ -696,9 +881,11 @@ func processIRForFormatWithDefaults(c *cli.Context, sweepData *wav.WAVData, reco
|
||||
return fmt.Errorf("cut-slope must be a positive multiple of 12 (got %d)", cutSlope)
|
||||
}
|
||||
if lowcutHz > 0 {
|
||||
log.Printf("Applying low-cut (high-pass) filter: %.2f Hz, slope: %d dB/oct", lowcutHz, cutSlope)
|
||||
recordedFiltered = convolve.CascadeLowcut(recordedFiltered, recSampleRate, lowcutHz, cutSlope)
|
||||
}
|
||||
if highcutHz > 0 {
|
||||
log.Printf("Applying high-cut (low-pass) filter: %.2f Hz, slope: %d dB/oct", highcutHz, cutSlope)
|
||||
recordedFiltered = convolve.CascadeHighcut(recordedFiltered, recSampleRate, highcutHz, cutSlope)
|
||||
}
|
||||
|
||||
@@ -735,12 +922,12 @@ func processIRForFormatWithDefaults(c *cli.Context, sweepData *wav.WAVData, reco
|
||||
|
||||
// Generate MPT if requested
|
||||
if generateMPT {
|
||||
// Use the original 96kHz IR for MPT generation
|
||||
// Use the filtered recorded sweep for MPT generation (same as RAW IR)
|
||||
var originalIR []float64
|
||||
if c.Bool("no-phase-correction") {
|
||||
originalIR = convolve.Deconvolve(sweepData.PCMData, recordedData.PCMData)
|
||||
originalIR = convolve.Deconvolve(sweepData.PCMData, recordedFiltered)
|
||||
} else {
|
||||
originalIR = convolve.DeconvolveWithPhaseCorrection(sweepData.PCMData, recordedData.PCMData)
|
||||
originalIR = convolve.DeconvolveWithPhaseCorrection(sweepData.PCMData, recordedFiltered)
|
||||
}
|
||||
originalIR = convolve.TrimSilence(originalIR, 1e-5)
|
||||
mptIR := convolve.MinimumPhaseTransform(originalIR)
|
||||
@@ -819,12 +1006,12 @@ func generateIRForFormatWithDefaults(c *cli.Context, sweepData *wav.WAVData, rec
|
||||
|
||||
// Generate MPT if requested
|
||||
if generateMPT {
|
||||
// Use the original 96kHz IR for MPT generation
|
||||
// Use the filtered recorded sweep for MPT generation (same as RAW IR)
|
||||
var originalIR []float64
|
||||
if c.Bool("no-phase-correction") {
|
||||
originalIR = convolve.Deconvolve(sweepData.PCMData, recordedData.PCMData)
|
||||
originalIR = convolve.Deconvolve(sweepData.PCMData, recordedFiltered)
|
||||
} else {
|
||||
originalIR = convolve.DeconvolveWithPhaseCorrection(sweepData.PCMData, recordedData.PCMData)
|
||||
originalIR = convolve.DeconvolveWithPhaseCorrection(sweepData.PCMData, recordedFiltered)
|
||||
}
|
||||
originalIR = convolve.TrimSilence(originalIR, 1e-5)
|
||||
mptIR := convolve.MinimumPhaseTransform(originalIR)
|
||||
@@ -853,7 +1040,7 @@ func main() {
|
||||
app := &cli.App{
|
||||
Name: "valhallir-deconvolver",
|
||||
Usage: "Deconvolve sweep and recorded WAV files to create impulse responses",
|
||||
Version: "v1.1.0",
|
||||
Version: "v1.2.1",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "sweep",
|
||||
@@ -865,7 +1052,7 @@ func main() {
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "output",
|
||||
Usage: "Path to the output IR WAV file or directory for batch processing. Default: IRs subfolder in recorded directory",
|
||||
Usage: "Path to the output IR WAV file or directory for batch processing. Default: cabpack folder one directory level up from recorded directory",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "mpt",
|
||||
@@ -966,8 +1153,8 @@ func main() {
|
||||
log.Printf("No command-line options provided, using default cabpack mode")
|
||||
recordedPath = execDir
|
||||
sweepPath = filepath.Join(recordedPath, "sweep.wav")
|
||||
// Create IRs folder one directory level up
|
||||
outputPath = filepath.Join(filepath.Dir(recordedPath), "IRs")
|
||||
// Create cabpack folder one directory level up
|
||||
outputPath = filepath.Join(filepath.Dir(recordedPath), "cabpack")
|
||||
cabpackMode = true
|
||||
log.Printf("Using recorded directory: %s", recordedPath)
|
||||
log.Printf("Looking for sweep file: %s", sweepPath)
|
||||
@@ -982,10 +1169,10 @@ func main() {
|
||||
sweepPath = filepath.Join(recordedPath, "sweep.wav")
|
||||
}
|
||||
if !c.IsSet("output") {
|
||||
// If recorded is a directory, use IRs folder one level up, otherwise use parent directory
|
||||
// If recorded is a directory, use cabpack folder one level up, otherwise use parent directory
|
||||
recordedInfo, err := os.Stat(recordedPath)
|
||||
if err == nil && recordedInfo.IsDir() {
|
||||
outputPath = filepath.Join(filepath.Dir(recordedPath), "IRs")
|
||||
outputPath = filepath.Join(filepath.Dir(recordedPath), "cabpack")
|
||||
} else {
|
||||
outputPath = filepath.Dir(recordedPath)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user