{"id":20020503,"url":"https://github.com/shakfu/cysox","last_synced_at":"2026-03-14T10:15:24.582Z","repository":{"id":113536409,"uuid":"333321897","full_name":"shakfu/cysox","owner":"shakfu","description":"A python wrapper of libsox using cython","archived":false,"fork":false,"pushed_at":"2026-01-22T08:01:26.000Z","size":5126,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-22T21:11:06.903Z","etag":null,"topics":["cython","libsox","python3","sox"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shakfu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"docs/contributing.rst","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-01-27T06:10:20.000Z","updated_at":"2026-01-22T08:03:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"2b50512d-2fd2-4f2d-91da-08b15078d782","html_url":"https://github.com/shakfu/cysox","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/shakfu/cysox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fcysox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fcysox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fcysox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fcysox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shakfu","download_url":"https://codeload.github.com/shakfu/cysox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fcysox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29130113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T18:55:47.139Z","status":"ssl_error","status_checked_at":"2026-02-05T18:55:04.010Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cython","libsox","python3","sox"],"created_at":"2024-11-13T08:32:38.766Z","updated_at":"2026-03-14T10:15:24.575Z","avatar_url":"https://github.com/shakfu.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cysox\n\n[![PyPI](https://img.shields.io/pypi/v/cysox)](https://pypi.org/project/cysox/)\n[![Python](https://img.shields.io/pypi/pyversions/cysox)](https://pypi.org/project/cysox/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\nA Pythonic audio processing library which uses cython to wrap [libsox](https://github.com/chirlu/sox).\n\n## Features\n\n- **Simple API**: Convert, analyze, and play audio with one-liners\n- **Typed Effects**: 28 base effect classes with IDE autocomplete and validation\n- **54 Effect Presets**: Ready-to-use composite effects for voice, lo-fi, drums, mastering, and more\n- **Drum Loop Tools**: Slice loops by BPM, create stutter effects, apply beat-synced processing\n- **High Performance**: Direct C bindings through Cython, KissFFT-accelerated onset detection\n- **Zero Configuration**: Auto-initialization, no manual setup required\n- **Cross-Platform**: macOS, Linux (Windows placeholder)\n\n## Installation\n\nNote that cysox only works on macOS and Linux.\n\n```sh\npip install cysox\n```\n\n## Command Line Interface\n\n```sh\n# Show version\ncysox --version\n\n# Get audio file info\ncysox info audio.wav\n\n# Convert audio files\ncysox convert input.wav output.mp3\ncysox convert input.wav output.wav --rate 48000 --channels 1\ncysox convert input.wav output.wav -p Telephone\n\n# Play audio\ncysox play audio.wav\n\n# Concatenate files\ncysox concat intro.wav main.wav outro.wav -o full.wav\n\n# List available effect presets\ncysox preset list\ncysox preset list drums          # Filter by category\n\n# Get preset info and parameters\ncysox preset info Chipmunk\n\n# Apply a preset to audio\ncysox preset apply Telephone input.wav output.wav\ncysox preset apply Chipmunk input.wav output.wav --intensity=2.0\n\n# Slice audio into segments\ncysox slice drums.wav output_dir/ -n 8\ncysox slice drums.wav output_dir/ --bpm 120 --beats 1\ncysox slice drums.wav output_dir/ -n 4 -p DrumPunch\n\n# Slice at detected transients (automatic beat detection)\n# -t threshold (e.g. 0.3), -s sensitivity (default 1.5), -m method (default hfc)\ncysox slice drums.wav output_dir/ -t 0.3\ncysox slice drums.wav output_dir/ -t 0.2 -s 1.2 -m flux\n\n# Create stutter effects\ncysox stutter drums.wav stutter.wav -d 0.125 -r 8\ncysox stutter drums.wav stutter.wav -s 0.5 -d 0.25 -r 4 -p GatedReverb\n```\n\n## Quick Start\n\n```python\nimport cysox\nfrom cysox import fx\n\n# Get audio file info\ninfo = cysox.info('audio.wav')\nprint(f\"Duration: {info['duration']:.2f}s, Sample rate: {info['sample_rate']} Hz\")\n\n# Convert with effects\ncysox.convert('input.wav', 'output.mp3', effects=[\n    fx.Normalize(),\n    fx.Reverb(reverberance=60),\n    fx.Fade(fade_in=0.5, fade_out=1.0),\n])\n\n# Play audio (macOS/Linux)\ncysox.play('audio.wav')\n\n# Play with effects\ncysox.play('audio.wav', effects=[fx.Volume(db=-6)])\n```\n\n## Core Functions\n\n### `cysox.info(path) -\u003e dict`\n\nGet audio file metadata:\n\n```python\ninfo = cysox.info('audio.wav')\n# Returns: {\n#     'path': 'audio.wav',\n#     'format': 'wav',\n#     'duration': 11.5,\n#     'sample_rate': 44100,\n#     'channels': 2,\n#     'bits_per_sample': 16,\n#     'samples': 507150,\n#     'encoding': 'signed-integer',\n# }\n```\n\n### `cysox.convert(input, output, effects=[], **options)`\n\nConvert audio files with optional effects and format options:\n\n```python\n# Simple format conversion\ncysox.convert('input.wav', 'output.mp3')\n\n# With effects\ncysox.convert('input.wav', 'output.wav', effects=[\n    fx.Volume(db=3),\n    fx.Bass(gain=5),\n    fx.Reverb(),\n])\n\n# With format options\ncysox.convert('input.wav', 'output.wav',\n    sample_rate=48000,\n    channels=1,\n    bits=24,\n)\n```\n\n### `cysox.stream(path, chunk_size=8192) -\u003e Iterator[memoryview]`\n\nStream audio samples for processing:\n\n```python\nimport numpy as np\n\nfor chunk in cysox.stream('large.wav', chunk_size=8192):\n    arr = np.frombuffer(chunk, dtype=np.int32)\n    process(arr)\n```\n\n### `cysox.play(path, effects=[])`\n\nPlay audio to the default audio device:\n\n```python\ncysox.play('audio.wav')\ncysox.play('audio.wav', effects=[fx.Volume(db=-6), fx.Reverb()])\n```\n\n### `cysox.concat(inputs, output)`\n\nConcatenate multiple audio files:\n\n```python\ncysox.concat(['intro.wav', 'main.wav', 'outro.wav'], 'full.wav')\n```\n\nAll input files must have the same sample rate and channel count.\n\n## Effects Module\n\nThe `cysox.fx` module provides 28 base effect classes and 54 composite presets:\n\n### Volume \u0026 Dynamics\n```python\nfx.Volume(db=3)                    # Adjust volume in dB\nfx.Gain(db=6)                      # Apply gain\nfx.Normalize(level=-3)             # Normalize to target level\n```\n\n### Equalization\n```python\nfx.Bass(gain=5, frequency=100)     # Boost/cut bass\nfx.Treble(gain=-2, frequency=3000) # Boost/cut treble\nfx.Equalizer(frequency=1000, width=1.0, gain=3)\n```\n\n### Filters\n```python\nfx.HighPass(frequency=200)         # Remove low frequencies\nfx.LowPass(frequency=8000)         # Remove high frequencies\nfx.BandPass(frequency=1000, width=100)\nfx.BandReject(frequency=60, width=10)  # Notch filter\n```\n\n### Spatial \u0026 Reverb\n```python\nfx.Reverb(reverberance=50, room_scale=100)\nfx.Echo(gain_in=0.8, gain_out=0.9, delays=[100], decays=[0.5])\nfx.Chorus()\nfx.Flanger()\n```\n\n### Time-Based\n```python\nfx.Trim(start=1.0, end=5.0)        # Extract portion\nfx.Pad(before=0.5, after=1.0)      # Add silence\nfx.Speed(factor=1.5)               # Change speed (affects pitch)\nfx.Tempo(factor=1.5)               # Change tempo (preserves pitch)\nfx.Pitch(cents=100)                # Shift pitch (preserves tempo)\nfx.Reverse()                       # Reverse audio\nfx.Fade(fade_in=0.5, fade_out=1.0) # Fade in/out\nfx.Repeat(count=3)                 # Repeat audio\n```\n\n### Conversion\n```python\nfx.Rate(sample_rate=48000)         # Resample\nfx.Channels(channels=1)            # Change channel count\nfx.Remix(out_spec=[[1, 2]])        # Custom channel mixing\nfx.Dither()                        # Add dither\n```\n\n### Composite Effects\n\nCreate reusable effect combinations:\n\n```python\nfrom cysox.fx import CompositeEffect, HighPass, LowPass, Reverb, Volume\n\nclass TelephoneEffect(CompositeEffect):\n    \"\"\"Simulate telephone audio quality.\"\"\"\n\n    @property\n    def effects(self):\n        return [\n            HighPass(frequency=300),\n            LowPass(frequency=3400),\n            Volume(db=-3),\n        ]\n\n# Use like any other effect\ncysox.convert('input.wav', 'output.wav', effects=[TelephoneEffect()])\n```\n\n## Effect Presets\n\nThe library includes 54 ready-to-use composite effect presets organized by category:\n\n### Voice Effects\n```python\nfx.Chipmunk(intensity=1.8)         # High-pitched voice\nfx.DeepVoice(intensity=0.6)        # Low, slowed voice\nfx.Robot(intensity=70)             # Metallic robotic voice\nfx.HauntedVoice(pitch_shift=5)     # Spooky ghost effect\nfx.VocalClarity(presence_boost=4)  # Enhanced vocal presence\nfx.Whisper()                       # Intimate whisper effect\n```\n\n### Lo-Fi Effects\n```python\nfx.Telephone(sample_rate=8000)     # Classic telephone sound\nfx.AMRadio()                       # AM radio broadcast\nfx.Megaphone(volume_boost=6)       # Bullhorn effect\nfx.Underwater(depth=500)           # Submerged/muffled sound\nfx.VinylWarmth(bass_boost=3)       # Warm vinyl aesthetic\nfx.LoFiHipHop(warmth=4)            # Lo-fi hip hop style\nfx.Cassette()                      # Cassette tape degradation\n```\n\n### Spatial Effects\n```python\nfx.SmallRoom(wetness=30)           # Intimate room reverb\nfx.LargeHall(size=100, decay=70)   # Concert hall ambience\nfx.Cathedral()                     # Church reverb\nfx.Bathroom()                      # Tiled room reverb\nfx.Stadium()                       # Arena with echo\n```\n\n### Broadcast Effects\n```python\nfx.Podcast()                       # Voice cleanup + presence\nfx.RadioDJ(presence=4)             # Punchy broadcast voice\nfx.Voiceover()                     # Professional VO processing\nfx.Intercom()                      # PA system effect\nfx.WalkieTalkie()                  # Two-way radio\n```\n\n### Musical Effects\n```python\nfx.EightiesChorus(depth=4)         # Classic 80s chorus\nfx.DreamyPad()                     # Ethereal ambient texture\nfx.SlowedReverb(slow_factor=0.85)  # Slowed + reverb aesthetic\nfx.SlapbackEcho(delay_ms=120)      # Rockabilly short delay\nfx.DubDelay(tempo_ms=375)          # Rhythmic dub delays\nfx.JetFlanger()                    # Extreme flanger sweep\nfx.ShoegazeWash()                  # Heavy reverb/chorus wash\n```\n\n### Drum Loop Effects\n```python\nfx.HalfTime(preserve_pitch=True)   # Slow to half speed\nfx.DoubleTime(preserve_pitch=True) # Speed up to double\nfx.DrumPunch(punch=4, attack=3)    # Enhance punch and attack\nfx.DrumCrisp(brightness=4)         # Crisp, bright drums\nfx.DrumFat(fatness=5)              # Thick, heavy drums\nfx.Breakbeat()                     # Classic breakbeat processing\nfx.VintageBreak()                  # Lo-fi sampled break sound\nfx.DrumRoom(room_size=40)          # Natural room ambience\nfx.GatedReverb()                   # 80s gated reverb\nfx.DrumSlice(start=0, duration=0.5)# Extract a segment\nfx.ReverseCymbal(fade_duration=0.5)# Reverse riser effect\nfx.LoopReady()                     # Prepare for seamless looping\n```\n\n### Mastering Effects\n```python\nfx.BroadcastLimiter(target_level=-1)  # Broadcast-ready limiting\nfx.WarmMaster(warmth=1.5)             # Warm mastering preset\nfx.BrightMaster(air=2)                # Bright/airy mastering\nfx.LoudnessMaster(target_level=-0.3)  # Maximum loudness\n```\n\n### Cleanup Effects\n```python\nfx.RemoveRumble(cutoff=60)         # High-pass for rumble\nfx.RemoveHiss(cutoff=12000)        # Low-pass for tape hiss\nfx.RemoveHum(frequency=60)         # Notch filter for hum (50/60Hz)\nfx.CleanVoice()                    # Basic voice cleanup\nfx.TapeRestoration()               # Restore tape recordings\n```\n\n### Transition Effects\n```python\nfx.FadeInOut(fade_in_secs=0.3, fade_out_secs=0.3)\nfx.CrossfadeReady(fade_duration=0.3)\n```\n\n### Chaining Presets\n\nPresets can be combined with each other and base effects:\n\n```python\ncysox.convert('input.wav', 'output.wav', effects=[\n    fx.RemoveRumble(),      # Cleanup first\n    fx.VinylWarmth(),       # Apply lo-fi aesthetic\n    fx.SmallRoom(),         # Add room ambience\n    fx.WarmMaster(),        # Final mastering\n])\n```\n\n## Drum Loop Slicing\n\ncysox provides utilities for slicing drum loops and creating stutter effects.\n\n### `cysox.slice_loop()` - Split Loops into Segments\n\nSplit an audio file into multiple segment files:\n\n```python\nimport cysox\nfrom cysox import fx\n\n# Slice into equal parts\nslices = cysox.slice_loop('drums.wav', 'output_dir/', slices=8)\n# Creates: output_dir/drums_slice_000.wav through drums_slice_007.wav\n\n# Slice by BPM (one beat per slice)\nslices = cysox.slice_loop('drums.wav', 'output_dir/', bpm=120, beats_per_slice=1)\n\n# Slice with effects applied to each segment\nslices = cysox.slice_loop('drums.wav', 'output_dir/',\n    slices=8,\n    effects=[fx.DrumPunch()]\n)\n```\n\n**Parameters:**\n- `path`: Input audio file\n- `output_dir`: Directory for slice files (created if needed)\n- `slices`: Number of equal slices (default: 4)\n- `bpm`: Calculate slice duration from BPM (overrides `slices`)\n- `beats_per_slice`: Beats per slice when using BPM (default: 1)\n- `beat_duration`: Explicit duration per slice in seconds\n- `threshold`: Onset detection threshold 0.0-1.0 (enables automatic transient slicing)\n- `sensitivity`: Onset detection sensitivity 1.0-3.0 (default: 1.5)\n- `onset_method`: Detection method - 'hfc', 'flux', 'energy', or 'complex'\n- `output_format`: Output format (default: \"wav\")\n- `effects`: Effects to apply to each slice\n\n**Returns:** List of created file paths\n\n### Automatic Transient Slicing\n\nSlice loops automatically at detected transients (drum hits, etc.):\n\n```python\n# Slice at detected onsets with default sensitivity\nslices = cysox.slice_loop('drums.wav', 'output_dir/', threshold=0.3)\n\n# More sensitive detection (catches subtle hits)\nslices = cysox.slice_loop('drums.wav', 'output_dir/',\n    threshold=0.2,\n    sensitivity=1.2\n)\n\n# Use different detection method\nslices = cysox.slice_loop('drums.wav', 'output_dir/',\n    threshold=0.3,\n    onset_method='flux'  # Good for tonal changes\n)\n```\n\n### `cysox.onset` - Direct Onset Detection\n\nFor more control, use the onset detection module directly:\n\n```python\nfrom cysox import onset\n\n# Detect onsets in a file\nonsets = onset.detect('drums.wav', threshold=0.3)\nprint(f\"Found {len(onsets)} transients\")\nfor t in onsets:\n    print(f\"  {t:.3f}s\")\n\n# With custom parameters\nonsets = onset.detect('drums.wav',\n    threshold=0.3,      # Detection threshold (0.0-1.0)\n    sensitivity=1.5,    # Peak picking sensitivity (1.0-3.0)\n    min_spacing=0.05,   # Min time between onsets (seconds)\n    method='hfc'        # 'hfc', 'flux', 'energy', or 'complex'\n)\n```\n\n**Detection Methods:**\n\n- **`hfc`** (default) - High-Frequency Content\n  - Weights frequency bins by their index, emphasizing high frequencies\n  - High frequencies are prominent in transient attacks (the \"click\" of a drum hit)\n  - Best for: drums, percussion, plucked instruments\n  - Fast and reliable for most percussive material\n\n- **`flux`** - Spectral Flux\n  - Measures the change in spectral energy between consecutive frames\n  - Detects when the frequency content changes significantly\n  - Best for: mixed material, melodic instruments, detecting note changes\n  - Good all-around choice when HFC misses softer onsets\n\n- **`energy`** - Energy-based\n  - Simply measures the RMS energy (loudness) of each frame\n  - Fastest method, minimal computation\n  - Best for: very clean recordings, isolated drums, quick processing\n  - May miss onsets that are spectrally distinct but similar in volume\n\n- **`complex`** - Complex Domain\n  - Analyzes both magnitude AND phase of the spectrum\n  - Detects deviations from expected phase trajectories\n  - Best for: maximum accuracy, subtle onsets, research applications\n  - Slowest method but catches onsets other methods miss\n\n**Understanding threshold vs sensitivity:**\n\n`threshold` (0.0-1.0) and `sensitivity` (1.0-3.0) control different stages:\n\n- **threshold** - Global minimum floor\n  - Sets the absolute minimum level a peak must reach\n  - Applied to the normalized detection function (0-1 scale)\n  - Lower values = more sensitive, catches quieter transients\n  - `threshold=0.3` means peaks must reach at least 30% of max energy\n  - Think of it as: \"ignore everything below this level\"\n\n- **sensitivity** - Adaptive peak picking strictness\n  - Controls how much a peak must exceed the *local average*\n  - Uses a moving median filter to compute the local baseline\n  - Higher values = stricter, only picks prominent peaks\n  - `sensitivity=1.5` means a peak must be 1.5x the local median\n  - Think of it as: \"how much must a peak stand out from neighbors\"\n\n**Typical combinations:**\n- Drums with clear hits: `threshold=0.3, sensitivity=1.5` (defaults)\n- Subtle transients: `threshold=0.2, sensitivity=1.2`\n- Only loud hits: `threshold=0.5, sensitivity=2.0`\n\n### `cysox.stutter()` - Create Stutter Effects\n\nExtract a segment and repeat it:\n\n```python\n# Basic stutter: 8x repeat of first 1/8 note at 120 BPM\ncysox.stutter('drums.wav', 'stutter.wav',\n    segment_duration=0.125,  # 1/8 note at 120 BPM\n    repeats=8\n)\n\n# Stutter from a specific position (e.g., the snare hit)\ncysox.stutter('drums.wav', 'snare_stutter.wav',\n    segment_start=0.5,       # Start at 0.5 seconds\n    segment_duration=0.125,\n    repeats=4\n)\n\n# Stutter with effects\ncysox.stutter('drums.wav', 'stutter_punchy.wav',\n    segment_duration=0.25,\n    repeats=4,\n    effects=[fx.DrumPunch(), fx.DrumRoom()]\n)\n```\n\n**Parameters:**\n- `path`: Input audio file\n- `output_path`: Output file path\n- `segment_start`: Start position in seconds (default: 0)\n- `segment_duration`: Length of segment in seconds (default: 0.125)\n- `repeats`: Total times segment plays (default: 8)\n- `effects`: Effects to apply after stuttering\n\n### Practical Examples\n\n#### Chop an Amen Break\n\n```python\nimport cysox\nfrom cysox import fx\n\n# Get loop info\ninfo = cysox.info('amen.wav')\nprint(f\"Duration: {info['duration']:.3f}s\")\n\n# Assuming 2-bar loop at 175 BPM\nbpm = 175\n\n# Slice into individual beats\nslices = cysox.slice_loop('amen.wav', 'amen_beats/', bpm=bpm)\nprint(f\"Created {len(slices)} beat slices\")\n\n# Slice into 16th notes with breakbeat processing\nslices = cysox.slice_loop('amen.wav', 'amen_16ths/',\n    slices=16,\n    effects=[fx.Breakbeat()]\n)\n\n# Create kick stutter fill\ncysox.stutter('amen.wav', 'kick_fill.wav',\n    segment_start=0,\n    segment_duration=info['duration'] / 16,  # First 16th note\n    repeats=16\n)\n```\n\n#### Process Drum Loops\n\n```python\n# Half-time for slow, heavy feel\ncysox.convert('drums.wav', 'halftime.wav', effects=[fx.HalfTime()])\n\n# Lo-fi vintage break sound\ncysox.convert('drums.wav', 'vintage.wav', effects=[\n    fx.VintageBreak(),\n    fx.DrumRoom(wetness=20)\n])\n\n# 80s gated reverb snare\ncysox.convert('drums.wav', 'gated.wav', effects=[fx.GatedReverb()])\n\n# Full processing chain\ncysox.convert('drums.wav', 'processed.wav', effects=[\n    fx.RemoveRumble(cutoff=40),\n    fx.DrumPunch(punch=5, attack=4),\n    fx.DrumRoom(room_size=30, wetness=20),\n    fx.BroadcastLimiter(),\n])\n\n## Low-Level API\n\nFor advanced use cases, access the full libsox bindings:\n\n```python\nfrom cysox import sox\n\n# Manual initialization (high-level API handles this automatically)\nsox.init()\n\n# Open files\ninput_fmt = sox.Format('input.wav')\noutput_fmt = sox.Format('output.wav', signal=input_fmt.signal, mode='w')\n\n# Build effects chain\nchain = sox.EffectsChain(input_fmt.encoding, output_fmt.encoding)\n\ne = sox.Effect(sox.find_effect(\"input\"))\ne.set_options([input_fmt])\nchain.add_effect(e, input_fmt.signal, input_fmt.signal)\n\ne = sox.Effect(sox.find_effect(\"vol\"))\ne.set_options([\"3dB\"])\nchain.add_effect(e, input_fmt.signal, input_fmt.signal)\n\ne = sox.Effect(sox.find_effect(\"output\"))\ne.set_options([output_fmt])\nchain.add_effect(e, input_fmt.signal, input_fmt.signal)\n\n# Process\nchain.flow_effects()\n\n# Cleanup\ninput_fmt.close()\noutput_fmt.close()\nsox.quit()\n```\n\n## Building from Source\n\n### macOS\n\n```sh\nbrew install sox libsndfile mad libpng flac lame mpg123 libogg opus opusfile libvorbis\nmake\nmake test\n```\n\n### Linux\n\n```sh\nsudo apt-get install libsox-dev libsndfile1-dev pkg-config\nmake\nmake test\n```\n\n## Status\n\nComprehensive test suite covering all functionality. All libsox C examples ported to Python (effects chains, waveform analysis, trim, concatenation, format conversion).\n\n## Known Issues\n\n- **Memory I/O**: libsox memory I/O functions have platform issues (tests skipped)\n- **Init/Quit Cycles**: Use high-level API to avoid init/quit issues (handled automatically)\n\nSee [KNOWN_LIMITATIONS.md](https://github.com/shakfu/cysox/blob/main/KNOWN_LIMITATIONS.md) for details.\n\n## Platform Support\n\n- **macOS**: Full support\n- **Linux**: Full support\n- **Windows**: Placeholder (contributions welcome)\n\n## Building Documentation\n\n```sh\npip install mkdocs-material\nmake docs          # Build static site\nmake docs-serve    # Live preview at http://localhost:8000\n```\n\n## License\n\nMIT\n\nKissFFT (vendored in `vendor/kissfft/`) is BSD-3-Clause licensed. See `vendor/kissfft/COPYING`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshakfu%2Fcysox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshakfu%2Fcysox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshakfu%2Fcysox/lists"}