breaks-machine 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,204 @@
1
+ # breaks-machine Development Guide
2
+
3
+ CLI tool for time-stretching drum breaks to target BPMs while preserving transient quality.
4
+
5
+ ## Project Overview
6
+
7
+ **breaks-machine** is a command-line tool designed to time-stretch drum breaks to specific BPMs using Rubberband's industry-standard algorithm. It's perfect for preparing breaks for hardware samplers, live performance, or production workflows.
8
+
9
+ **Tech Stack:**
10
+ - **pyrubberband**: Python wrapper for Rubberband time-stretching
11
+ - **librosa**: Audio analysis and BPM detection
12
+ - **soundfile**: Audio I/O for WAV/FLAC files
13
+ - **click**: CLI framework
14
+ - **Python 3.13** with **uv** for package management
15
+
16
+ ## Key Components
17
+
18
+ ### Core Modules
19
+
20
+ - **[cli.py](../../src/breaks_machine/cli.py)** - Click-based CLI entry point
21
+ - Handles command-line arguments and user input
22
+ - Orchestrates the processing pipeline
23
+ - Entry point: `breaks-machine stretch`
24
+
25
+ - **[detector.py](../../src/breaks_machine/detector.py)** - BPM detection
26
+ - Parses BPM from filename patterns (e.g., `amen_170.wav`)
27
+ - Multi-strategy librosa detection with subdivision correction
28
+ - Priority: manual override → filename → auto-detection
29
+
30
+ - **[stretcher.py](../../src/breaks_machine/stretcher.py)** - Rubberband wrapper
31
+ - Time-stretching with crispness=5 (optimized for drums)
32
+ - Ratio calculation: `target_bpm / source_bpm`
33
+ - Preserves transients and minimizes phase artifacts
34
+
35
+ - **[converter.py](../../src/breaks_machine/converter.py)** - Format conversion
36
+ - Optional sample rate conversion
37
+ - Bit depth conversion (16/24-bit)
38
+ - Stereo to mono downmixing
39
+
40
+ - **[processor.py](../../src/breaks_machine/processor.py)** - Pipeline orchestration
41
+ - Single file and batch directory processing
42
+ - Output structure: `output/{filename}/{filename}_{bpm}bpm.{ext}`
43
+ - Target parsing (single, multiple, range modes)
44
+
45
+ ## Development Workflow
46
+
47
+ ### Testing
48
+
49
+ ```bash
50
+ # Run all tests
51
+ uv run pytest tests
52
+
53
+ # Run with coverage
54
+ uv run pytest tests --cov=src/breaks_machine
55
+
56
+ # Run specific test file
57
+ uv run pytest tests/test_detector.py -v
58
+
59
+ # Watch mode (if using pytest-watch)
60
+ uv run ptw tests/
61
+ ```
62
+
63
+ ### Code Quality
64
+
65
+ ```bash
66
+ # Format code
67
+ uvx ruff format
68
+
69
+ # Lint and fix issues
70
+ uvx ruff check --fix
71
+
72
+ # Check formatting without changes
73
+ uvx ruff format --check
74
+
75
+ # Full quality check
76
+ uvx ruff check && uvx ruff format --check
77
+ ```
78
+
79
+ ### Manual Testing
80
+
81
+ Test with real drum breaks in the `breaks/` directory:
82
+
83
+ ```bash
84
+ # Test auto-detection
85
+ uv run breaks-machine stretch breaks/FR_Drum_Loop_160.wav -t 140
86
+
87
+ # Test with manual BPM override
88
+ uv run breaks-machine stretch breaks/amen_RUDE.wav --bpm 175 -t 140
89
+
90
+ # Test batch processing
91
+ uv run breaks-machine stretch breaks/ --targets 90,120,140 -o test_output/
92
+ ```
93
+
94
+ ## Audio Processing Notes
95
+
96
+ ### Supported Formats
97
+
98
+ - **Input**: WAV, FLAC
99
+ - **Output**: Same format as input (preserves original format by default)
100
+
101
+ ### Rubberband Crispness Settings
102
+
103
+ The `--crispness` parameter (0-6) controls transient preservation:
104
+
105
+ - **0-2**: Smoother, less transient preservation (not ideal for drums)
106
+ - **3-4**: Balanced
107
+ - **5**: Default for breaks-machine - optimized for drums
108
+ - **6**: Maximum transient preservation
109
+
110
+ ### BPM Detection Improvements
111
+
112
+ Recent improvements to `detector.py`:
113
+
114
+ - **Multi-strategy detection**: Tries multiple tempo priors (120, 140, 170 BPM)
115
+ - **Subdivision correction**: Accounts for common misdetections (half-time, 2/3 time, etc.)
116
+ - **Smart selection**: Prefers direct detections over derived subdivisions
117
+ - **Breakbeat bias**: Favors common breakbeat range (140-180 BPM)
118
+
119
+ This significantly improved accuracy on complex breaks like the Amen break (now detects 172 BPM vs previous 117 BPM).
120
+
121
+ ### System Dependencies
122
+
123
+ Required for time-stretching functionality:
124
+
125
+ - **rubberband-cli**: The actual time-stretching engine
126
+ - **libsndfile1**: Audio file I/O library
127
+ - **ffmpeg**: Audio codec support
128
+
129
+ **Installation:**
130
+
131
+ **macOS:**
132
+ ```bash
133
+ brew install rubberband
134
+ ```
135
+
136
+ **Ubuntu/Debian:**
137
+ ```bash
138
+ sudo apt-get install rubberband-cli libsndfile1 ffmpeg
139
+ ```
140
+
141
+ **Windows:**
142
+ Download from https://breakfastquay.com/rubberband/ and add to PATH.
143
+
144
+ **Optional: Use devcontainer** - Copy `.devcontainer-template/` to `.devcontainer/` for automatic setup.
145
+
146
+ ## Quick Reference
147
+
148
+ ### Common Commands
149
+
150
+ - Add dependency: `uv add <package>`
151
+ - Add dev dependency: `uv add --dev <package>`
152
+ - Run CLI: `uv run breaks-machine stretch <file> [options]`
153
+ - Run tests: `uv run pytest tests`
154
+ - Format code: `uvx ruff format`
155
+ - Lint code: `uvx ruff check --fix`
156
+
157
+ ### CLI Usage Examples
158
+
159
+ ```bash
160
+ # Single target
161
+ breaks-machine stretch amen_170.wav --target 140
162
+
163
+ # Multiple targets
164
+ breaks-machine stretch break.wav --targets 90,120,140,160
165
+
166
+ # Range with step
167
+ breaks-machine stretch break.wav --range 80-160 --step 10
168
+
169
+ # Batch directory
170
+ breaks-machine stretch ./breaks/ -t 140 -o ./output/
171
+
172
+ # With format conversion
173
+ breaks-machine stretch break.wav -t 140 --sample-rate 44100 --mono
174
+
175
+ # Manual BPM override
176
+ breaks-machine stretch break.wav --bpm 175 -t 140
177
+ ```
178
+
179
+ ### Important Files
180
+
181
+ - `pyproject.toml` - Project metadata and dependency specifications
182
+ - `uv.lock` - Locked dependency tree (always commit!)
183
+ - `.python-version` - Python version pinning (3.13)
184
+ - `src/breaks_machine/` - Source code
185
+ - `tests/` - Test suite
186
+ - `breaks/` - Test audio files for manual testing
187
+ - `.devcontainer-template/` - Optional devcontainer configuration
188
+ - `.github/workflows/ci.yml` - CI/CD pipeline configuration
189
+
190
+ ## Detailed Documentation
191
+
192
+ For more information about the development environment and tooling:
193
+
194
+ - **uv quick reference**: [.claude/rules/uv-guide.md](rules/uv-guide.md)
195
+ - **CI/CD pipeline**: [.claude/rules/cicd.md](rules/cicd.md)
196
+ - **Troubleshooting**: [.claude/rules/troubleshooting.md](rules/troubleshooting.md)
197
+
198
+ ## Project Principles
199
+
200
+ - **Reproducibility**: `uv.lock` ensures identical dependencies across all environments
201
+ - **Standard Python package**: Installable via pip/uv without Docker
202
+ - **Optional devcontainer**: Available for zero-friction setup if preferred
203
+ - **Quality first**: Comprehensive test suite with 58 tests, all passing
204
+ - **Fast feedback**: Linting and formatting enforced in CI/CD
@@ -0,0 +1,409 @@
1
+ # CI/CD Pipeline Guide
2
+
3
+ ## Pipeline Overview
4
+
5
+ **File**: `.github/workflows/ci.yml`
6
+
7
+ ### Pipeline Stages
8
+
9
+ ```
10
+ Trigger (push to any branch, pull request to main)
11
+
12
+ Job: Lint, Format Check, and Test
13
+
14
+ 1. Checkout code (actions/checkout@v4)
15
+
16
+ 2. Setup Python (actions/setup-python@v5)
17
+
18
+ 3. Install uv (astral-sh/setup-uv@v7 with caching)
19
+
20
+ 4. Lint (uvx ruff check)
21
+
22
+ 5. Format check (uvx ruff format --check)
23
+
24
+ 6. Test (uv run pytest tests)
25
+ ```
26
+
27
+ ### Key Characteristics
28
+
29
+ - **Runner**: `ubuntu-latest` (Ubuntu 22.04 with Python pre-installed)
30
+ - **Python setup**: Via `actions/setup-python@v5` reading `.python-version`
31
+ - **uv setup**: Via official `astral-sh/setup-uv@v7` action
32
+ - **Consistency**: Uses same uv commands as local development
33
+ - **Lock file**: Uses `uv.lock` for reproducible dependencies
34
+ - **Caching**: Built-in uv cache via `enable-cache: true`
35
+
36
+ ## Current Configuration
37
+
38
+ ```yaml
39
+ name: CI
40
+
41
+ on:
42
+ push:
43
+ branches: ["*"]
44
+ pull_request:
45
+ branches: ["main"]
46
+
47
+ jobs:
48
+ lint-format-test:
49
+ name: Lint, Format Check, and Test
50
+ runs-on: ubuntu-latest
51
+
52
+ steps:
53
+ - name: Checkout code
54
+ uses: actions/checkout@v4
55
+
56
+ - name: Set up Python
57
+ uses: actions/setup-python@v5
58
+ with:
59
+ python-version-file: ".python-version"
60
+
61
+ - name: Install uv
62
+ uses: astral-sh/setup-uv@v7
63
+ with:
64
+ version: "0.9.22"
65
+ enable-cache: true
66
+
67
+ - name: Verify uv installation
68
+ run: uv --version
69
+
70
+ - name: Lint with Ruff
71
+ run: uvx ruff check
72
+
73
+ - name: Check code formatting with Ruff
74
+ run: uvx ruff format --check
75
+
76
+ - name: Run tests with pytest
77
+ run: uv run pytest tests
78
+ ```
79
+
80
+ ## How It Works
81
+
82
+ ### Step 1: Checkout Code
83
+ ```yaml
84
+ - name: Checkout code
85
+ uses: actions/checkout@v4
86
+ ```
87
+ Clones the repository code into the runner workspace.
88
+
89
+ ### Step 2: Set up Python
90
+ ```yaml
91
+ - name: Set up Python
92
+ uses: actions/setup-python@v5
93
+ with:
94
+ python-version-file: ".python-version"
95
+ ```
96
+ Installs Python 3.13 by reading the `.python-version` file. Uses GitHub's pre-cached Python versions for fast setup.
97
+
98
+ ### Step 3: Install uv
99
+ ```yaml
100
+ - name: Install uv
101
+ uses: astral-sh/setup-uv@v7
102
+ with:
103
+ version: "0.9.22"
104
+ enable-cache: true
105
+ ```
106
+ Installs uv package manager with version pinning and automatic caching enabled.
107
+
108
+ ### Step 4: Lint
109
+ ```bash
110
+ uvx ruff check
111
+ ```
112
+ Runs ruff linter. Fails workflow if linting errors found.
113
+
114
+ ### Step 5: Format Check
115
+ ```bash
116
+ uvx ruff format --check
117
+ ```
118
+ Verifies code is properly formatted without modifying files.
119
+
120
+ ### Step 6: Test
121
+ ```bash
122
+ uv run pytest tests
123
+ ```
124
+ Installs dependencies from `uv.lock` automatically and runs pytest.
125
+
126
+ ## Trigger Conditions
127
+
128
+ **Push to any branch**:
129
+ ```yaml
130
+ on:
131
+ push:
132
+ branches: ["*"]
133
+ ```
134
+
135
+ **Pull requests to main**:
136
+ ```yaml
137
+ on:
138
+ pull_request:
139
+ branches: ["main"]
140
+ ```
141
+
142
+ **Both triggers combined**:
143
+ ```yaml
144
+ on:
145
+ push:
146
+ branches: ["*"]
147
+ pull_request:
148
+ branches: ["main"]
149
+ ```
150
+
151
+ ### Common Modifications
152
+
153
+ **Run on specific branch patterns**:
154
+ ```yaml
155
+ on:
156
+ push:
157
+ branches:
158
+ - main
159
+ - 'feature/**'
160
+ - 'release/*'
161
+ ```
162
+
163
+ **Run only on tagged commits**:
164
+ ```yaml
165
+ on:
166
+ push:
167
+ tags:
168
+ - 'v*'
169
+
170
+ jobs:
171
+ release:
172
+ name: Release build
173
+ runs-on: ubuntu-latest
174
+ steps:
175
+ - uses: actions/checkout@v4
176
+ - run: docker build -t myapp:${{ github.ref_name }} .
177
+ ```
178
+
179
+ **Scheduled builds**:
180
+ ```yaml
181
+ on:
182
+ schedule:
183
+ - cron: '0 0 * * *' # Daily at midnight UTC
184
+ push:
185
+ branches: ["main"]
186
+
187
+ jobs:
188
+ nightly-tests:
189
+ name: Nightly tests
190
+ runs-on: ubuntu-latest
191
+ steps:
192
+ - uses: actions/checkout@v4
193
+ - uses: actions/setup-python@v5
194
+ with:
195
+ python-version-file: ".python-version"
196
+ - uses: astral-sh/setup-uv@v7
197
+ with:
198
+ enable-cache: true
199
+ - run: uv run pytest tests
200
+ ```
201
+
202
+ **Matrix builds** (test multiple Python versions):
203
+ ```yaml
204
+ jobs:
205
+ test:
206
+ runs-on: ubuntu-latest
207
+ strategy:
208
+ matrix:
209
+ python-version: ["3.11", "3.12", "3.13"]
210
+ steps:
211
+ - uses: actions/checkout@v4
212
+ - uses: actions/setup-python@v5
213
+ with:
214
+ python-version: ${{ matrix.python-version }}
215
+ - uses: astral-sh/setup-uv@v7
216
+ with:
217
+ enable-cache: true
218
+ - run: uv run pytest tests
219
+ ```
220
+
221
+ ## Secrets and Environment Variables
222
+
223
+ ### Setting Secrets
224
+
225
+ 1. GitHub repo → Settings → Secrets and variables → Actions
226
+ 2. Click "New repository secret"
227
+ 3. Add name and value (e.g., `API_KEY`, `DATABASE_URL`, `DOCKER_PASSWORD`)
228
+
229
+ ### Using Secrets
230
+
231
+ ```yaml
232
+ jobs:
233
+ test:
234
+ runs-on: ubuntu-latest
235
+ steps:
236
+ - uses: actions/checkout@v4
237
+ - uses: actions/setup-python@v5
238
+ with:
239
+ python-version-file: ".python-version"
240
+ - uses: astral-sh/setup-uv@v7
241
+ with:
242
+ enable-cache: true
243
+ - name: Run tests with secrets
244
+ env:
245
+ API_KEY: ${{ secrets.API_KEY }}
246
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
247
+ run: uv run pytest tests
248
+ ```
249
+
250
+ ### Environment Variables
251
+
252
+ ```yaml
253
+ jobs:
254
+ test:
255
+ runs-on: ubuntu-latest
256
+ env:
257
+ DEBUG: "true"
258
+ ENVIRONMENT: "ci"
259
+ steps:
260
+ - uses: actions/checkout@v4
261
+ - run: uv run pytest tests # DEBUG and ENVIRONMENT available
262
+ ```
263
+
264
+ ### Reusable Workflows
265
+
266
+ Create `.github/workflows/reusable-test.yml`:
267
+ ```yaml
268
+ name: Reusable Test Workflow
269
+
270
+ on:
271
+ workflow_call:
272
+ inputs:
273
+ python-version:
274
+ required: false
275
+ type: string
276
+ default: "3.13"
277
+
278
+ jobs:
279
+ test:
280
+ runs-on: ubuntu-latest
281
+ steps:
282
+ - uses: actions/checkout@v4
283
+ - uses: actions/setup-python@v5
284
+ with:
285
+ python-version: ${{ inputs.python-version }}
286
+ - uses: astral-sh/setup-uv@v7
287
+ with:
288
+ enable-cache: true
289
+ - run: uv run pytest tests
290
+ ```
291
+
292
+ Use it in another workflow:
293
+ ```yaml
294
+ jobs:
295
+ call-test:
296
+ uses: ./.github/workflows/reusable-test.yml
297
+ with:
298
+ python-version: "3.13"
299
+ ```
300
+
301
+ ## Common CI Issues
302
+
303
+ ### Tests Pass Locally But Fail in CI
304
+
305
+ **Cause**: Uncommitted `uv.lock` or local-only changes.
306
+
307
+ **Solution**:
308
+ ```bash
309
+ git status # Check for uncommitted files
310
+ git add uv.lock
311
+ git commit -m "Update lock file"
312
+ git push
313
+ ```
314
+
315
+ ### Workflow Not Triggering
316
+
317
+ **Causes**:
318
+ 1. Workflow file has syntax errors (check Actions tab for parsing errors)
319
+ 2. GitHub Actions not enabled for the repository
320
+ 3. Branch protection rules blocking workflow runs
321
+
322
+ **Solution**:
323
+ 1. Validate YAML syntax
324
+ 2. Settings → Actions → General → Enable "Allow all actions and reusable workflows"
325
+ 3. Settings → Branches → Check branch protection settings
326
+
327
+ ### Caching Not Working
328
+
329
+ Check workflow logs for cache hit/miss messages:
330
+ ```
331
+ Run astral-sh/setup-uv@v7
332
+ Cache hit: ~/.cache/uv
333
+ ```
334
+
335
+ If cache misses frequently, verify:
336
+ 1. `enable-cache: true` is set in setup-uv step
337
+ 2. `uv.lock` file is committed
338
+ 3. Cache hasn't been manually cleared
339
+
340
+ ### Debugging
341
+
342
+ Run the same commands locally:
343
+ ```bash
344
+ uvx ruff check
345
+ uvx ruff format --check
346
+ uv run pytest tests
347
+ ```
348
+
349
+ Use GitHub Actions locally with [act](https://github.com/nektos/act):
350
+ ```bash
351
+ # Install act
352
+ brew install act # macOS
353
+ # or: https://github.com/nektos/act#installation
354
+
355
+ # Run workflow locally
356
+ act push
357
+ ```
358
+
359
+ ## Best Practices
360
+
361
+ 1. **Keep CI commands identical to local**: Use same commands in CI as local development
362
+ 2. **Always commit `uv.lock`**: Ensures CI uses same dependency versions
363
+ 3. **Fail fast**: Put linting before tests (faster feedback)
364
+ 4. **Use caching**: Enable built-in caching with `enable-cache: true`
365
+ 5. **Pin action versions**: Use `@v4` not `@latest` for reproducibility
366
+ 6. **Protect main branch**: Require status checks to pass before merging (Settings → Branches → Branch protection rules)
367
+ 7. **Use concurrency control**: Prevent multiple runs on same PR
368
+ ```yaml
369
+ concurrency:
370
+ group: ${{ github.workflow }}-${{ github.ref }}
371
+ cancel-in-progress: true
372
+ ```
373
+
374
+ ## Viewing Workflow Results
375
+
376
+ 1. **Actions tab**: Click "Actions" in repository navigation
377
+ 2. **Workflow runs**: See all runs with status (success, failure, in progress)
378
+ 3. **Logs**: Click a run → Click job name → Expand steps to see detailed logs
379
+ 4. **Re-run failed jobs**: Click "Re-run jobs" button on failed runs
380
+
381
+ ## Branch Protection
382
+
383
+ Require CI to pass before merging:
384
+
385
+ 1. Settings → Branches → Add branch protection rule
386
+ 2. Branch name pattern: `main`
387
+ 3. Enable "Require status checks to pass before merging"
388
+ 4. Search for and select: "Lint, Format Check, and Test"
389
+ 5. Enable "Require branches to be up to date before merging"
390
+ 6. Save changes
391
+
392
+ ## Cost & Limits
393
+
394
+ **Free tier** (public repos):
395
+ - 2,000 minutes/month for private repos
396
+ - Unlimited minutes for public repos
397
+
398
+ **This project's usage**:
399
+ - ~2-3 minutes per run (first run with cache miss)
400
+ - ~1-2 minutes per run (subsequent runs with cache hit)
401
+ - Well within free tier limits
402
+
403
+ ## Resources
404
+
405
+ - **GitHub Actions docs**: https://docs.github.com/en/actions
406
+ - **Using uv in GitHub Actions**: https://docs.astral.sh/uv/guides/integration/github/
407
+ - **astral-sh/setup-uv**: https://github.com/astral-sh/setup-uv
408
+ - **Workflow syntax**: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
409
+ - **uv documentation**: https://docs.astral.sh/uv/