|
| 1 | +# wav-files-concat |
| 2 | + |
| 3 | +A lightweight Rust CLI tool for concatenating multiple WAV files from a directory (including subdirectories) into a single output WAV file. It ensures all input files have compatible formats (channels, sample rate, and sample format) before proceeding. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- Recursively scans directories for `.wav` files (case-insensitive). |
| 8 | +- Validates format compatibility across all files. |
| 9 | +- Supports both float (32-bit) and int (16-bit) sample formats. |
| 10 | +- Handles errors gracefully with detailed context using `anyhow`. |
| 11 | +- Includes comprehensive unit tests. |
| 12 | + |
| 13 | +## Installation |
| 14 | + |
| 15 | +### From Source |
| 16 | + |
| 17 | +1. Clone the repository: |
| 18 | + ```bash |
| 19 | + git clone https://github.com/RustedBytes/wav-files-concat |
| 20 | + cd wav-files-concat |
| 21 | + ``` |
| 22 | + |
| 23 | +2. Build and install: |
| 24 | + ```bash |
| 25 | + cargo install --path . |
| 26 | + ``` |
| 27 | + |
| 28 | +## Usage |
| 29 | + |
| 30 | +```bash |
| 31 | +wav-files-concat <INPUT_DIR> <OUTPUT_FILE> |
| 32 | +``` |
| 33 | + |
| 34 | +- `<INPUT_DIR>`: Path to the directory containing WAV files (required). |
| 35 | +- `<OUTPUT_FILE>`: Path to the output WAV file (required). |
| 36 | + |
| 37 | +The tool will: |
| 38 | +1. Find all WAV files recursively. |
| 39 | +2. Validate they share the same audio spec. |
| 40 | +3. Concatenate them in the order discovered by the filesystem walker. |
| 41 | + |
| 42 | +## Examples |
| 43 | + |
| 44 | +### Basic Usage |
| 45 | + |
| 46 | +Concatenate all WAV files in `./audio/` to `combined.wav`: |
| 47 | + |
| 48 | +```bash |
| 49 | +wav-files-concat ./audio/ combined.wav |
| 50 | +``` |
| 51 | + |
| 52 | +Output: |
| 53 | +``` |
| 54 | +Scanning input directory for WAV files... |
| 55 | +Found 3 WAV files. |
| 56 | +Determining WAV format from first file... |
| 57 | +Format: 2 channels, 44100 Hz, Float |
| 58 | +Verifying formats of remaining files... |
| 59 | +All files compatible. |
| 60 | +Creating output file: combined.wav |
| 61 | +Concatenating files... |
| 62 | + 1/3: ./audio/track1.wav |
| 63 | + 2/3: ./audio/subdir/track2.wav |
| 64 | + 3/3: ./audio/track3.wav |
| 65 | +Concatenation complete. |
| 66 | +``` |
| 67 | + |
| 68 | +### Error Handling |
| 69 | + |
| 70 | +If files have incompatible formats: |
| 71 | +``` |
| 72 | +Error: Incompatible WAV format in ./audio/incompatible.wav: WavSpec { channels: 1, sample_rate: 48000, bits_per_sample: 16, sample_format: Int } |
| 73 | +``` |
| 74 | + |
| 75 | +If no WAV files are found: |
| 76 | +``` |
| 77 | +Error: No WAV files found in the input directory |
| 78 | +``` |
| 79 | + |
| 80 | +## Dependencies |
| 81 | + |
| 82 | +This project uses the following crates: |
| 83 | + |
| 84 | +| Crate | Purpose | Version (approx.) | |
| 85 | +|-------|---------|-------------------| |
| 86 | +| `anyhow` | Error handling with context | ^1.0 | |
| 87 | +| `clap` | Command-line argument parsing | ^4.0 | |
| 88 | +| `hound` | WAV file reading/writing | ^3.5 | |
| 89 | +| `walkdir` | Recursive directory traversal | ^2.3 | |
| 90 | +| `tempfile` (dev) | Temporary files for testing | ^3.0 | |
| 91 | + |
| 92 | +See `Cargo.toml` for exact versions. |
| 93 | + |
| 94 | +## Testing |
| 95 | + |
| 96 | +Run the test suite: |
| 97 | + |
| 98 | +```bash |
| 99 | +cargo test |
| 100 | +``` |
| 101 | + |
| 102 | +The tests cover: |
| 103 | +- Finding WAV files (including subdirs, case-insensitivity, multiples, and edge cases like no files). |
| 104 | +- Retrieving WAV specs from valid/invalid files. |
| 105 | +- Copying samples with format mismatches. |
| 106 | + |
| 107 | +All tests use temporary directories and mock WAV files for isolation. |
| 108 | + |
| 109 | +## Building |
| 110 | + |
| 111 | +```bash |
| 112 | +cargo build --release |
| 113 | +``` |
| 114 | + |
| 115 | +The binary will be in `target/release/wav-files-concat`. |
0 commit comments