cycsound 0.1.0__cp314-cp314-macosx_15_0_arm64.whl
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.
- cycsound/__init__.py +33 -0
- cycsound/__main__.py +275 -0
- cycsound/_core.cpython-314-darwin.so +0 -0
- cycsound-0.1.0.dist-info/METADATA +315 -0
- cycsound-0.1.0.dist-info/RECORD +8 -0
- cycsound-0.1.0.dist-info/WHEEL +5 -0
- cycsound-0.1.0.dist-info/entry_points.txt +3 -0
- cycsound-0.1.0.dist-info/licenses/LICENSE +26 -0
cycsound/__init__.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""cycsound - Cython bindings for Csound."""
|
|
2
|
+
|
|
3
|
+
from cycsound._core import (
|
|
4
|
+
# Module-level functions
|
|
5
|
+
initialize,
|
|
6
|
+
set_opcode_dir,
|
|
7
|
+
get_version,
|
|
8
|
+
get_api_version,
|
|
9
|
+
get_size_of_myflt,
|
|
10
|
+
# Enums (Python Enum classes)
|
|
11
|
+
Msg,
|
|
12
|
+
Color,
|
|
13
|
+
Mask,
|
|
14
|
+
# Enums (cpdef enums from Csound API)
|
|
15
|
+
Status,
|
|
16
|
+
FileType,
|
|
17
|
+
# Classes
|
|
18
|
+
Csound,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"initialize",
|
|
23
|
+
"set_opcode_dir",
|
|
24
|
+
"get_version",
|
|
25
|
+
"get_api_version",
|
|
26
|
+
"get_size_of_myflt",
|
|
27
|
+
"Msg",
|
|
28
|
+
"Color",
|
|
29
|
+
"Mask",
|
|
30
|
+
"Status",
|
|
31
|
+
"FileType",
|
|
32
|
+
"Csound",
|
|
33
|
+
]
|
cycsound/__main__.py
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"""
|
|
2
|
+
cycsound CLI - Command-line interface for Csound operations.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
cycsound play <file.csd> Play a CSD file
|
|
6
|
+
cycsound render <file.csd> Render CSD to audio file
|
|
7
|
+
cycsound info Show Csound version info
|
|
8
|
+
cycsound check <file.csd> Validate a CSD file
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from cycsound import Csound, get_version, get_api_version
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _setup_quiet(cs):
|
|
19
|
+
"""Configure Csound for quiet operation."""
|
|
20
|
+
cs.set_message_level(0) # Suppress all messages first
|
|
21
|
+
cs.set_option("-d") # Suppress displays
|
|
22
|
+
cs.set_option("-m0") # Minimal messages
|
|
23
|
+
cs.set_option("-+msg_color=0") # Disable color codes
|
|
24
|
+
cs.set_option("-O null") # Send output info to null
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def cmd_play(args):
|
|
28
|
+
"""Play a CSD file in real-time."""
|
|
29
|
+
csd_path = Path(args.file)
|
|
30
|
+
if not csd_path.exists():
|
|
31
|
+
print(f"Error: File not found: {csd_path}", file=sys.stderr)
|
|
32
|
+
return 1
|
|
33
|
+
|
|
34
|
+
cs = Csound()
|
|
35
|
+
|
|
36
|
+
# Set options
|
|
37
|
+
cs.set_option("-odac") # Real-time audio output
|
|
38
|
+
|
|
39
|
+
if args.quiet:
|
|
40
|
+
_setup_quiet(cs)
|
|
41
|
+
|
|
42
|
+
if args.input:
|
|
43
|
+
cs.set_option(f"-iadc:{args.input}")
|
|
44
|
+
|
|
45
|
+
if args.output:
|
|
46
|
+
cs.set_option(f"-odac:{args.output}")
|
|
47
|
+
|
|
48
|
+
# Compile and perform
|
|
49
|
+
result = cs.compile_csd(str(csd_path))
|
|
50
|
+
if result != 0:
|
|
51
|
+
print(f"Error: Failed to compile {csd_path}", file=sys.stderr)
|
|
52
|
+
return 1
|
|
53
|
+
|
|
54
|
+
cs.start()
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
while not cs.perform_ksmps():
|
|
58
|
+
pass
|
|
59
|
+
except KeyboardInterrupt:
|
|
60
|
+
print("\nInterrupted by user")
|
|
61
|
+
|
|
62
|
+
cs.cleanup()
|
|
63
|
+
return 0
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def cmd_render(args):
|
|
67
|
+
"""Render a CSD file to an audio file."""
|
|
68
|
+
csd_path = Path(args.file)
|
|
69
|
+
if not csd_path.exists():
|
|
70
|
+
print(f"Error: File not found: {csd_path}", file=sys.stderr)
|
|
71
|
+
return 1
|
|
72
|
+
|
|
73
|
+
# Determine output filename
|
|
74
|
+
if args.output:
|
|
75
|
+
output_path = args.output
|
|
76
|
+
else:
|
|
77
|
+
output_path = csd_path.with_suffix(".wav")
|
|
78
|
+
|
|
79
|
+
cs = Csound()
|
|
80
|
+
|
|
81
|
+
# Set options
|
|
82
|
+
cs.set_option(f"-o{output_path}")
|
|
83
|
+
|
|
84
|
+
if args.format:
|
|
85
|
+
cs.set_option(f"--format={args.format}")
|
|
86
|
+
|
|
87
|
+
if args.sample_rate:
|
|
88
|
+
cs.set_option(f"-r{args.sample_rate}")
|
|
89
|
+
|
|
90
|
+
if args.ksmps:
|
|
91
|
+
cs.set_option(f"-k{args.ksmps}")
|
|
92
|
+
|
|
93
|
+
if args.quiet:
|
|
94
|
+
_setup_quiet(cs)
|
|
95
|
+
else:
|
|
96
|
+
print(f"Rendering: {csd_path} -> {output_path}")
|
|
97
|
+
|
|
98
|
+
# Compile and perform
|
|
99
|
+
result = cs.compile_csd(str(csd_path))
|
|
100
|
+
if result != 0:
|
|
101
|
+
print(f"Error: Failed to compile {csd_path}", file=sys.stderr)
|
|
102
|
+
return 1
|
|
103
|
+
|
|
104
|
+
cs.start()
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
while not cs.perform_ksmps():
|
|
108
|
+
pass
|
|
109
|
+
except KeyboardInterrupt:
|
|
110
|
+
print("\nInterrupted by user", file=sys.stderr)
|
|
111
|
+
cs.cleanup()
|
|
112
|
+
return 1
|
|
113
|
+
|
|
114
|
+
cs.cleanup()
|
|
115
|
+
|
|
116
|
+
if not args.quiet:
|
|
117
|
+
print(f"Done: {output_path}")
|
|
118
|
+
|
|
119
|
+
return 0
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def cmd_info(args):
|
|
123
|
+
"""Display Csound version information."""
|
|
124
|
+
version = get_version()
|
|
125
|
+
api_version = get_api_version()
|
|
126
|
+
|
|
127
|
+
major = version // 1000
|
|
128
|
+
minor = (version % 1000) // 10
|
|
129
|
+
patch = version % 10
|
|
130
|
+
|
|
131
|
+
print(f"Csound version: {major}.{minor}.{patch} ({version})")
|
|
132
|
+
print(f"API version: {api_version}")
|
|
133
|
+
|
|
134
|
+
if args.verbose:
|
|
135
|
+
from cycsound import get_size_of_myflt
|
|
136
|
+
myflt_size = get_size_of_myflt()
|
|
137
|
+
myflt_type = "double" if myflt_size == 8 else "float"
|
|
138
|
+
print(f"MYFLT type: {myflt_type} ({myflt_size} bytes)")
|
|
139
|
+
|
|
140
|
+
return 0
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def cmd_check(args):
|
|
144
|
+
"""Validate a CSD file without performing it."""
|
|
145
|
+
csd_path = Path(args.file)
|
|
146
|
+
if not csd_path.exists():
|
|
147
|
+
print(f"Error: File not found: {csd_path}", file=sys.stderr)
|
|
148
|
+
return 1
|
|
149
|
+
|
|
150
|
+
cs = Csound()
|
|
151
|
+
|
|
152
|
+
# Syntax check only
|
|
153
|
+
cs.set_option("--syntax-check-only")
|
|
154
|
+
|
|
155
|
+
if args.quiet:
|
|
156
|
+
_setup_quiet(cs)
|
|
157
|
+
else:
|
|
158
|
+
cs.set_option("-d")
|
|
159
|
+
cs.set_option("-m0")
|
|
160
|
+
|
|
161
|
+
result = cs.compile_csd(str(csd_path))
|
|
162
|
+
|
|
163
|
+
if result == 0:
|
|
164
|
+
if not args.quiet:
|
|
165
|
+
print(f"OK: {csd_path}")
|
|
166
|
+
return 0
|
|
167
|
+
else:
|
|
168
|
+
if not args.quiet:
|
|
169
|
+
print(f"FAILED: {csd_path}", file=sys.stderr)
|
|
170
|
+
return 1
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def cmd_eval(args):
|
|
174
|
+
"""Evaluate Csound orchestra code."""
|
|
175
|
+
cs = Csound()
|
|
176
|
+
cs.set_option("-n") # No audio output
|
|
177
|
+
|
|
178
|
+
if args.quiet:
|
|
179
|
+
_setup_quiet(cs)
|
|
180
|
+
else:
|
|
181
|
+
cs.set_option("-d")
|
|
182
|
+
cs.set_option("-m0")
|
|
183
|
+
|
|
184
|
+
# Set up basic header if not provided
|
|
185
|
+
code = args.code
|
|
186
|
+
if "sr" not in code and "sr=" not in code:
|
|
187
|
+
code = "sr = 44100\nksmps = 32\nnchnls = 2\n0dbfs = 1\n" + code
|
|
188
|
+
|
|
189
|
+
result = cs.compile_orc(code)
|
|
190
|
+
if result != 0:
|
|
191
|
+
print("Error: Failed to compile orchestra code", file=sys.stderr)
|
|
192
|
+
return 1
|
|
193
|
+
|
|
194
|
+
# If code contains return statement, evaluate and print result
|
|
195
|
+
if "return" in code.lower():
|
|
196
|
+
try:
|
|
197
|
+
value = cs.eval_code(code)
|
|
198
|
+
print(value)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
201
|
+
return 1
|
|
202
|
+
|
|
203
|
+
return 0
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def main(argv=None):
|
|
207
|
+
"""Main entry point for the cycsound CLI."""
|
|
208
|
+
parser = argparse.ArgumentParser(
|
|
209
|
+
prog="cycsound",
|
|
210
|
+
description="Csound CLI powered by cycsound",
|
|
211
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
212
|
+
epilog="""
|
|
213
|
+
Examples:
|
|
214
|
+
cycsound play myscore.csd Play a CSD file
|
|
215
|
+
cycsound render myscore.csd Render to myscore.wav
|
|
216
|
+
cycsound render -o out.wav file.csd Render to specific file
|
|
217
|
+
cycsound check myscore.csd Validate CSD syntax
|
|
218
|
+
cycsound info Show Csound version
|
|
219
|
+
""",
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
parser.add_argument(
|
|
223
|
+
"--version",
|
|
224
|
+
action="version",
|
|
225
|
+
version=f"cycsound {get_version() // 1000}.{(get_version() % 1000) // 10}",
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
229
|
+
|
|
230
|
+
# Play command
|
|
231
|
+
play_parser = subparsers.add_parser("play", help="Play a CSD file in real-time")
|
|
232
|
+
play_parser.add_argument("file", help="CSD file to play")
|
|
233
|
+
play_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress output")
|
|
234
|
+
play_parser.add_argument("-i", "--input", help="Audio input device")
|
|
235
|
+
play_parser.add_argument("-o", "--output", help="Audio output device")
|
|
236
|
+
play_parser.set_defaults(func=cmd_play)
|
|
237
|
+
|
|
238
|
+
# Render command
|
|
239
|
+
render_parser = subparsers.add_parser("render", help="Render CSD to audio file")
|
|
240
|
+
render_parser.add_argument("file", help="CSD file to render")
|
|
241
|
+
render_parser.add_argument("-o", "--output", help="Output audio file")
|
|
242
|
+
render_parser.add_argument("-f", "--format", help="Output format (wav, aiff, flac, ogg)")
|
|
243
|
+
render_parser.add_argument("-r", "--sample-rate", type=int, help="Sample rate override")
|
|
244
|
+
render_parser.add_argument("-k", "--ksmps", type=int, help="ksmps override")
|
|
245
|
+
render_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress output")
|
|
246
|
+
render_parser.set_defaults(func=cmd_render)
|
|
247
|
+
|
|
248
|
+
# Info command
|
|
249
|
+
info_parser = subparsers.add_parser("info", help="Show Csound version info")
|
|
250
|
+
info_parser.add_argument("-v", "--verbose", action="store_true", help="Show detailed info")
|
|
251
|
+
info_parser.set_defaults(func=cmd_info)
|
|
252
|
+
|
|
253
|
+
# Check command
|
|
254
|
+
check_parser = subparsers.add_parser("check", help="Validate a CSD file")
|
|
255
|
+
check_parser.add_argument("file", help="CSD file to validate")
|
|
256
|
+
check_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress output")
|
|
257
|
+
check_parser.set_defaults(func=cmd_check)
|
|
258
|
+
|
|
259
|
+
# Eval command
|
|
260
|
+
eval_parser = subparsers.add_parser("eval", help="Evaluate orchestra code")
|
|
261
|
+
eval_parser.add_argument("code", help="Orchestra code to evaluate")
|
|
262
|
+
eval_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress output")
|
|
263
|
+
eval_parser.set_defaults(func=cmd_eval)
|
|
264
|
+
|
|
265
|
+
args = parser.parse_args(argv)
|
|
266
|
+
|
|
267
|
+
if args.command is None:
|
|
268
|
+
parser.print_help()
|
|
269
|
+
return 0
|
|
270
|
+
|
|
271
|
+
return args.func(args)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
sys.exit(main())
|
|
Binary file
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cycsound
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Cython bindings for the Csound audio synthesis library
|
|
5
|
+
Keywords: audio,csound,cython,music,synthesis,dsp,sound
|
|
6
|
+
Author-Email: Shakeeb Alireza <shakfu@users.noreply.github.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Operating System :: MacOS
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
|
+
Classifier: Programming Language :: Cython
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
23
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Sound Synthesis
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering
|
|
25
|
+
Project-URL: Homepage, https://github.com/shakfu/cycsound
|
|
26
|
+
Project-URL: Repository, https://github.com/shakfu/cycsound
|
|
27
|
+
Project-URL: Issues, https://github.com/shakfu/cycsound/issues
|
|
28
|
+
Project-URL: Changelog, https://github.com/shakfu/cycsound/blob/main/CHANGELOG.md
|
|
29
|
+
Requires-Python: >=3.10
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# cycsound
|
|
33
|
+
|
|
34
|
+
Cython bindings for the Csound 6.x API.
|
|
35
|
+
|
|
36
|
+
## Overview
|
|
37
|
+
|
|
38
|
+
cycsound is a Cython wrapper for the [Csound](https://csound.com/) audio synthesis library, providing Python bindings for the `csound.h` C API. It offers an alternative to the default ctypes-based `ctcsound.py` wrapper included with Csound.
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
|
|
42
|
+
- **98% API coverage** of the Csound C API (216/219 functions)
|
|
43
|
+
- **Context manager support** for automatic resource cleanup
|
|
44
|
+
- **GIL release** for all blocking operations (enables true multi-threading)
|
|
45
|
+
- **Static linking support** on macOS (standalone wheels without Csound installation)
|
|
46
|
+
- **Platform support**: macOS, Linux, Windows
|
|
47
|
+
- **CLI** for common operations (play, render, check, info, eval)
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
pip install cycsound
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Building From Source
|
|
56
|
+
|
|
57
|
+
Prerequisites:
|
|
58
|
+
|
|
59
|
+
- Python >= 3.9
|
|
60
|
+
- Csound 6.x installed:
|
|
61
|
+
- **macOS**: CsoundLib64.framework in `/Library/Frameworks/`
|
|
62
|
+
- **Linux**: `libcsound64-dev` package
|
|
63
|
+
- **Windows**: Csound6_x64 in `C:/Program Files/`
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Clone the repository
|
|
67
|
+
git clone https://github.com/yourusername/cycsound.git
|
|
68
|
+
cd cycsound
|
|
69
|
+
|
|
70
|
+
# Install in development mode
|
|
71
|
+
make sync
|
|
72
|
+
|
|
73
|
+
# Or install directly
|
|
74
|
+
pip install .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Building Wheels
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Dynamic linking (requires Csound at runtime)
|
|
81
|
+
make wheel
|
|
82
|
+
|
|
83
|
+
# Static linking - standalone wheel (macOS only)
|
|
84
|
+
make wheel-static
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Command-Line Interface
|
|
88
|
+
|
|
89
|
+
cycsound includes a CLI for common Csound operations:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Play a CSD file
|
|
93
|
+
cycsound play myscore.csd
|
|
94
|
+
|
|
95
|
+
# Render to audio file
|
|
96
|
+
cycsound render myscore.csd # Creates myscore.wav
|
|
97
|
+
cycsound render -o output.wav myscore.csd # Specify output file
|
|
98
|
+
cycsound render -f flac -r 48000 myscore.csd # FLAC format, 48kHz
|
|
99
|
+
|
|
100
|
+
# Validate CSD syntax
|
|
101
|
+
cycsound check myscore.csd
|
|
102
|
+
|
|
103
|
+
# Show Csound version info
|
|
104
|
+
cycsound info
|
|
105
|
+
cycsound info -v # Verbose output
|
|
106
|
+
|
|
107
|
+
# Get help
|
|
108
|
+
cycsound --help
|
|
109
|
+
cycsound play --help
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### CLI Commands
|
|
113
|
+
|
|
114
|
+
| Command | Description |
|
|
115
|
+
|---------|-------------|
|
|
116
|
+
| `play <file>` | Play CSD file in real-time |
|
|
117
|
+
| `render <file>` | Render CSD to audio file |
|
|
118
|
+
| `check <file>` | Validate CSD syntax |
|
|
119
|
+
| `info` | Show Csound version |
|
|
120
|
+
| `eval <code>` | Evaluate orchestra code |
|
|
121
|
+
|
|
122
|
+
### Common Options
|
|
123
|
+
|
|
124
|
+
| Option | Description |
|
|
125
|
+
|--------|-------------|
|
|
126
|
+
| `-q, --quiet` | Suppress output |
|
|
127
|
+
| `-o, --output` | Output file/device |
|
|
128
|
+
| `-h, --help` | Show help |
|
|
129
|
+
|
|
130
|
+
## Quick Start
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
import cycsound
|
|
134
|
+
|
|
135
|
+
# Using context manager (recommended)
|
|
136
|
+
with cycsound.Csound() as cs:
|
|
137
|
+
cs.set_option("-odac") # Real-time audio output
|
|
138
|
+
cs.set_option("-d") # Suppress displays
|
|
139
|
+
cs.compile_orc("""
|
|
140
|
+
sr = 44100
|
|
141
|
+
ksmps = 32
|
|
142
|
+
nchnls = 2
|
|
143
|
+
0dbfs = 1
|
|
144
|
+
|
|
145
|
+
instr 1
|
|
146
|
+
asig oscil 0.5, 440
|
|
147
|
+
outs asig, asig
|
|
148
|
+
endin
|
|
149
|
+
""")
|
|
150
|
+
cs.read_score("i1 0 2")
|
|
151
|
+
cs.run() # Performs entire score
|
|
152
|
+
# cleanup() called automatically on exit
|
|
153
|
+
|
|
154
|
+
# Or with manual control
|
|
155
|
+
with cycsound.Csound() as cs:
|
|
156
|
+
cs.compile_csd("myscore.csd")
|
|
157
|
+
cs.start()
|
|
158
|
+
while not cs.perform_ksmps():
|
|
159
|
+
# Process each k-cycle
|
|
160
|
+
pass
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## API Reference
|
|
164
|
+
|
|
165
|
+
### Module-level Functions
|
|
166
|
+
|
|
167
|
+
| Function | Description |
|
|
168
|
+
|----------|-------------|
|
|
169
|
+
| `get_version()` | Returns Csound version (e.g., 6180 for 6.18.0) |
|
|
170
|
+
| `get_api_version()` | Returns API version |
|
|
171
|
+
| `get_size_of_myflt()` | Returns size of MYFLT type (4 or 8) |
|
|
172
|
+
| `initialize(flags=0)` | Initialize Csound library (rarely needed) |
|
|
173
|
+
| `set_opcode_dir(path)` | Set opcode directory override |
|
|
174
|
+
|
|
175
|
+
### Csound Class
|
|
176
|
+
|
|
177
|
+
Core methods for audio synthesis:
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
# Context manager support
|
|
181
|
+
with cycsound.Csound() as cs:
|
|
182
|
+
# ... use cs ...
|
|
183
|
+
# cleanup() called automatically
|
|
184
|
+
|
|
185
|
+
# Compilation
|
|
186
|
+
cs.compile_orc(orc_string) # Compile orchestra code
|
|
187
|
+
cs.compile_csd(filename) # Compile CSD file
|
|
188
|
+
cs.compile_csd_text(csd_string) # Compile CSD from string
|
|
189
|
+
cs.read_score(score_string) # Read score events
|
|
190
|
+
|
|
191
|
+
# Performance
|
|
192
|
+
cs.run() # Perform entire score (convenience method)
|
|
193
|
+
cs.start() # Prepare for performance
|
|
194
|
+
cs.perform() # Perform entire score (blocks)
|
|
195
|
+
cs.perform_ksmps() # Perform one control period
|
|
196
|
+
cs.perform_buffer() # Perform one buffer
|
|
197
|
+
cs.stop() # Stop performance
|
|
198
|
+
cs.cleanup() # Close audio/MIDI devices
|
|
199
|
+
cs.reset() # Reset for new performance
|
|
200
|
+
|
|
201
|
+
# Configuration
|
|
202
|
+
cs.set_option(option) # Set command-line option
|
|
203
|
+
cs.get_sr() / cs.get_kr() # Get sample/control rate
|
|
204
|
+
cs.get_ksmps() / cs.get_nchnls() # Get ksmps/channels
|
|
205
|
+
|
|
206
|
+
# Channels
|
|
207
|
+
cs.set_control_channel(name, value)
|
|
208
|
+
cs.get_control_channel(name)
|
|
209
|
+
cs.set_string_channel(name, value)
|
|
210
|
+
cs.get_string_channel(name)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Enums
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
# Status codes (return values from Csound operations)
|
|
217
|
+
cycsound.Status.SUCCESS # 0 - Operation succeeded
|
|
218
|
+
cycsound.Status.ERROR # -1 - General error
|
|
219
|
+
cycsound.Status.INITIALIZATION # -2 - Initialization error
|
|
220
|
+
cycsound.Status.PERFORMANCE # -3 - Performance error
|
|
221
|
+
cycsound.Status.MEMORY # -4 - Memory allocation error
|
|
222
|
+
cycsound.Status.SIGNAL # -5 - Signal received
|
|
223
|
+
|
|
224
|
+
# File types
|
|
225
|
+
cycsound.FileType.WAVE # WAV audio
|
|
226
|
+
cycsound.FileType.FLAC # FLAC audio
|
|
227
|
+
cycsound.FileType.OGG # OGG Vorbis audio
|
|
228
|
+
cycsound.FileType.UNIFIED_CSD # Csound CSD file
|
|
229
|
+
cycsound.FileType.STD_MIDI # Standard MIDI file
|
|
230
|
+
# ... and 60+ more file type constants
|
|
231
|
+
|
|
232
|
+
# Message types
|
|
233
|
+
cycsound.Msg.DEFAULT # Standard message
|
|
234
|
+
cycsound.Msg.ERROR # Error message
|
|
235
|
+
cycsound.Msg.WARNING # Warning message
|
|
236
|
+
|
|
237
|
+
# Message colors
|
|
238
|
+
cycsound.Color.FG_RED # Foreground colors
|
|
239
|
+
cycsound.Color.FG_GREEN
|
|
240
|
+
cycsound.Color.FG_BOLD # Text attributes
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Development
|
|
244
|
+
|
|
245
|
+
### Setup
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Initial setup
|
|
249
|
+
make sync
|
|
250
|
+
|
|
251
|
+
# Rebuild after code changes
|
|
252
|
+
make build
|
|
253
|
+
|
|
254
|
+
# Run tests
|
|
255
|
+
make test # All tests
|
|
256
|
+
make test-cli # CLI tests only
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Available Make Targets
|
|
260
|
+
|
|
261
|
+
| Target | Description |
|
|
262
|
+
|--------|-------------|
|
|
263
|
+
| `make` / `make build` | Build/rebuild the extension |
|
|
264
|
+
| `make sync` | Initial environment setup |
|
|
265
|
+
| `make test` | Run test suite |
|
|
266
|
+
| `make wheel` | Build wheel (dynamic linking) |
|
|
267
|
+
| `make wheel-static` | Build standalone wheel (macOS) |
|
|
268
|
+
| `make release` | Build static wheels for all Python versions |
|
|
269
|
+
| `make check` | Check distribution with twine |
|
|
270
|
+
| `make publish` | Publish to PyPI |
|
|
271
|
+
| `make publish-test` | Publish to TestPyPI |
|
|
272
|
+
| `make clean` | Remove build artifacts |
|
|
273
|
+
| `make help` | Show all targets |
|
|
274
|
+
|
|
275
|
+
### Static Build Requirements (macOS)
|
|
276
|
+
|
|
277
|
+
For `make wheel-static`, install dependencies via Homebrew:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
brew install libsndfile flac opus libvorbis libogg mpg123 lame
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Rationale
|
|
284
|
+
|
|
285
|
+
This project provides an alternative to the default ctypes-based wrapper. [Cython](https://cython.readthedocs.io/) offers several advantages over ctypes:
|
|
286
|
+
|
|
287
|
+
- Better performance for tight loops
|
|
288
|
+
- Direct C-level access to Csound internals
|
|
289
|
+
- Ability to release the GIL for true multi-threading
|
|
290
|
+
- Static linking for self-contained distribution
|
|
291
|
+
|
|
292
|
+
For more details, see this [comparison of wrapping approaches](https://stackoverflow.com/questions/1942298/wrapping-a-c-library-in-python-c-cython-or-ctypes).
|
|
293
|
+
|
|
294
|
+
## Status
|
|
295
|
+
|
|
296
|
+
- [x] Wrap enough to play arbitrary CSD files
|
|
297
|
+
- [x] Build static variant as wheel (macOS only)
|
|
298
|
+
- [x] 98% coverage of csound.h API (216/219 functions)
|
|
299
|
+
- [x] GIL release for all blocking operations
|
|
300
|
+
- [x] scikit-build-core based build system
|
|
301
|
+
- [x] Context manager support
|
|
302
|
+
- [x] Test suite (36 tests: core API, CLI, channels, threading, enums)
|
|
303
|
+
- [x] CI/CD with cibuildwheel (GitHub Actions)
|
|
304
|
+
- [ ] Complete wrapping of csound.h (remaining: 3 va_list callbacks)
|
|
305
|
+
- [ ] Include plugin support in wheel
|
|
306
|
+
- [ ] Feature parity with ctcsound.py
|
|
307
|
+
|
|
308
|
+
## Related Projects
|
|
309
|
+
|
|
310
|
+
- [ctcsound](https://github.com/csound/csound/blob/develop/interfaces/ctcsound.py) - Official ctypes-based Python wrapper
|
|
311
|
+
- [Csound](https://csound.com/) - The Csound audio synthesis system
|
|
312
|
+
|
|
313
|
+
## License
|
|
314
|
+
|
|
315
|
+
See [LICENSE](LICENSE) file.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
cycsound/__init__.py,sha256=gv-G06_JGVFWbsrlJFx1qnKKTHP3ouDyF6ANHB-woFA,563
|
|
2
|
+
cycsound/__main__.py,sha256=vCwJLxy0YdCZ1hvK3iC70ni9lgVM-fz0W2fdWpWUiGI,7915
|
|
3
|
+
cycsound/_core.cpython-314-darwin.so,sha256=UXpM5y6k7Vvoj3eIa3rREoGltwCzNgyuly_keDXkF4U,5056344
|
|
4
|
+
cycsound-0.1.0.dist-info/METADATA,sha256=jldgYvmxIPBG7w3p9YOhSUuoQ-ehB204UBCMxl2NwRY,9207
|
|
5
|
+
cycsound-0.1.0.dist-info/WHEEL,sha256=vigfwfBy7qR_O1e5CYhYthzx1fo46v39YFrvEex4Qro,114
|
|
6
|
+
cycsound-0.1.0.dist-info/entry_points.txt,sha256=T9IOPIGCM-Bty4Kpy4BFJU_FYBZedKedS_bn_wncu8E,53
|
|
7
|
+
cycsound-0.1.0.dist-info/licenses/LICENSE,sha256=6yxCBxfRa98CF9FfaLkfETHk6f6ufwtvHtvTP5wxSFw,1279
|
|
8
|
+
cycsound-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
All third-party code included, used, linked-to or wrapped preserves all
|
|
2
|
+
rights specified by its respective license. (see `docs/licenses` folder).
|
|
3
|
+
|
|
4
|
+
Otherwise, code in this project has the following license:
|
|
5
|
+
|
|
6
|
+
MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Shakeeb Alireza
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|