Import Guide¶
Where everything lives, and how to import it.
The Rule¶
Import from the subpackage that owns the domain:
# Object-oriented API, one subpackage per domain
from coremusic.audio import AudioFile, AudioFormat
from coremusic.base import AudioPlayer
from coremusic.midi import MIDIClient, MusicSequence
player = AudioPlayer()
audio = AudioFile("audio.wav")
sequence = MusicSequence()
# Functional C API (for performance)
from coremusic import capi
file_id = capi.audio_file_open_url("audio.wav")
capi.audio_file_close(file_id)
The top-level coremusic package deliberately exports nothing but
__version__. There is no flat namespace: coremusic.AudioFile does not
exist, and neither does the coremusic.objects package that earlier versions
had. See the Migration Guide if you are updating code written
against either.
Package Map¶
coremusic/
├── __init__.py # version only
├── capi.pyx # functional C API - every CoreAudio/CoreMIDI call
├── base.py # CoreAudioObject, AudioPlayer, NUMPY_AVAILABLE
├── exceptions.py # exception hierarchy
├── shortcuts.py # one-call helpers (play, convert, get_info, ...)
├── constants/ # enumerated CoreAudio/CoreMIDI constants
│
├── audio/ # audio domain
│ ├── core.py # AudioFile, AudioFormat, AudioQueue, AudioConverter
│ ├── units.py # AudioUnit, AudioComponent
│ ├── graph.py # AUGraph
│ ├── devices.py # AudioDevice, AudioDeviceManager
│ ├── clock.py # AudioClock, ClockTimeFormat
│ ├── utilities.py # conversion helpers, AudioEffectsChain
│ ├── async_io.py # AsyncAudioFile, AsyncAudioQueue
│ ├── analysis.py # AudioAnalyzer, LivePitchDetector
│ ├── slicing.py # AudioSlicer, SliceCollection
│ ├── streaming.py # AudioInputStream, AudioOutputStream, StreamGraph
│ ├── visualization.py# WaveformPlotter, SpectrogramPlotter
│ ├── buffer_pool.py # BufferPool
│ ├── mmap_file.py # MMapAudioFile
│ └── audiounit_host.py # AudioUnitHost, AudioUnitPlugin, AudioUnitChain
│
├── midi/ # MIDI domain
│ ├── core.py # MIDIClient, MIDIPort, MIDIEndpoint
│ ├── player.py # MusicPlayer, MusicSequence, MusicTrack
│ ├── utilities.py # MIDISequence, MIDITrack, MIDIEvent, MIDIRouter
│ ├── transform.py # Pipeline, Transpose, Quantize, Humanize, ...
│ └── link.py # LinkMIDIClock, LinkMIDISequencer
│
├── music/ # music theory
│ └── theory.py # Note, Scale, Chord, Interval, TimeSignature
│
├── utils/ # helpers
│ ├── scipy.py # SciPy-backed DSP
│ ├── fourcc.py # FourCC conversion
│ └── batch.py # parallel batch processing
│
├── cli/ # command-line interface
└── link.pyx # Ableton Link: LinkSession, SessionState, Clock
Classes are re-exported from each subpackage's __init__, so
from coremusic.audio import AudioAnalyzer and
from coremusic.audio.analysis import AudioAnalyzer both work. Prefer the
short form; reach for the module path when you want to be explicit about where
something comes from.
Audio¶
Core objects:
from coremusic.audio import (
AudioConverter,
AudioFile,
AudioFormat,
AudioQueue,
AudioUnit,
ExtendedAudioFile,
)
audio = AudioFile("audio.wav")
queue = AudioQueue.new_output(AudioFormat.pcm(44100.0, channels=2))
unit = AudioUnit.default_output()
Async I/O:
from coremusic.audio import AsyncAudioFile, AsyncAudioQueue
# Or from the module that defines them
from coremusic.audio.async_io import AsyncAudioFile
print(AsyncAudioFile, AsyncAudioQueue)
Analysis:
from coremusic.audio.analysis import (
AudioAnalyzer,
BeatInfo,
LivePitchDetector,
PitchInfo,
)
analyzer = AudioAnalyzer("audio.wav")
beats = analyzer.detect_beats()
print(f"{beats.tempo:.1f} BPM")
Slicing:
from coremusic.audio.slicing import AudioSlicer
slicer = AudioSlicer("audio.wav", method="onset")
slices = slicer.detect_slices()
print(f"{len(slices)} slices")
Visualization (requires coremusic[visualization]):
from coremusic.audio.visualization import (
FrequencySpectrumPlotter,
SpectrogramPlotter,
WaveformPlotter,
)
plotter = WaveformPlotter("audio.wav")
plotter.save("waveform.png")
AudioUnit hosting:
from coremusic.audio.audiounit_host import (
AudioUnitChain,
AudioUnitHost,
AudioUnitParameter,
AudioUnitPlugin,
AudioUnitPreset,
PresetManager,
)
host = AudioUnitHost()
plugin = host.load_plugin("AUMatrixReverb", type="effect")
plugin.dispose()
MIDI¶
Clients, ports, and endpoints:
from coremusic.midi import (
MIDIClient,
MIDIEndpoint,
MIDIInputPort,
MIDIOutputPort,
MusicPlayer,
MusicSequence,
MusicTrack,
get_destinations,
get_sources,
)
client = MIDIClient("MyApp")
client.dispose()
MIDI files and events:
from coremusic.midi import MIDIEvent, MIDISequence, MIDITrack
sequence = MIDISequence.load("song.mid")
print(f"{sequence.duration:.2f} beats")
Transformation pipeline:
from coremusic.midi import Humanize, Pipeline, Quantize, Transpose, transpose
# Class-based pipeline, or the one-call functions
pipeline = Pipeline([Transpose(semitones=5), Quantize(grid=0.25)])
transposed = transpose(sequence, 5)
Ableton Link integration:
# The submodule is reachable from the package, or by its full path
from coremusic.midi import link
from coremusic.midi.link import LinkMIDIClock, LinkMIDISequencer
print(link.MIDI_CLOCK, LinkMIDIClock, LinkMIDISequencer)
Music Theory¶
from coremusic.music.theory import Chord, ChordType, Note, Scale, ScaleType
c_major = Scale(Note("C", 4), ScaleType.MAJOR)
Constants and Exceptions¶
from coremusic.constants import AudioFileProperty, AudioFormatID, MIDIStatus
print(AudioFormatID.LINEAR_PCM, MIDIStatus.NOTE_ON)
from coremusic.exceptions import AudioFileError, CoreAudioError, MIDIError
# Every coremusic exception derives from CoreAudioError
print(issubclass(AudioFileError, CoreAudioError))
Utilities¶
SciPy-backed DSP (requires coremusic[analysis]):
# Individual helpers, or the module itself - handy for the availability flag
import coremusic.utils.scipy as spu
from coremusic.utils.scipy import (
SCIPY_AVAILABLE,
apply_lowpass_filter,
compute_spectrum,
resample_audio,
)
print(f"SciPy available: {spu.SCIPY_AVAILABLE}")
FourCC conversion:
from coremusic.utils.fourcc import fourcc_to_int, fourcc_to_str
print(fourcc_to_int("lpcm"), fourcc_to_str(1819304813))
# The same conversion exists in the functional API
from coremusic import capi
print(capi.fourchar_to_int("lpcm"), capi.int_to_fourchar(1819304813))
Ableton Link¶
from coremusic import link
session = link.LinkSession(bpm=120.0)
session.enabled = True
state = session.capture_app_session_state()
print(f"Tempo: {state.tempo} BPM")
clock = link.Clock()
print(f"Clock: {clock.micros()} us")
session.enabled = False
Shortcuts¶
For the common one-liners, coremusic.shortcuts wraps the objects above:
from coremusic.shortcuts import convert, get_info, play
info = get_info("audio.wav")
print(f"{info['duration']:.2f}s")
Functional API¶
Every CoreAudio and CoreMIDI call is available from coremusic.capi. The
object layer is built on it, and the two interoperate: objects expose their
underlying id through object_id, and functions that take an id accept it.
from coremusic import capi
# Direct C function calls
file_id = capi.audio_file_open_url("audio.wav")
data, count = capi.audio_file_read_packets(file_id, 0, 1024)
capi.audio_file_close(file_id)
# Constants are exposed as get_* functions
property_id = capi.get_audio_file_property_data_format()
format_id = capi.fourchar_to_int('lpcm')
Best Practices¶
Import what you use, from where it lives.
Do not use wildcard imports. They pull in a large namespace and hide where a name came from:
Group imports in the usual order - standard library, third party, then coremusic:
Optional Dependencies¶
Some modules need extras. Import them anyway - each exposes a flag rather than failing at import time:
| Module | Extra | Flag |
|---|---|---|
coremusic.audio.analysis |
coremusic[analysis] |
NUMPY_AVAILABLE, SCIPY_AVAILABLE |
coremusic.utils.scipy |
coremusic[analysis] |
SCIPY_AVAILABLE |
coremusic.audio.visualization |
coremusic[visualization] |
MATPLOTLIB_AVAILABLE |
from coremusic.audio import NUMPY_AVAILABLE, AudioFile
from coremusic.audio.analysis import AudioAnalyzer
from coremusic.midi import MIDIClient
if NUMPY_AVAILABLE:
...
Troubleshooting¶
ModuleNotFoundError: No module named 'coremusic' - the package is not
installed in the interpreter you are running. pip install coremusic, or
uv sync in a checkout.
ModuleNotFoundError: No module named 'coremusic.objects' - that package
was removed in 0.2.3. Its contents moved to coremusic.audio,
coremusic.midi, coremusic.exceptions, and coremusic.base. See the
Migration Guide.
ImportError: cannot import name 'AudioFile' from 'coremusic' - there is
no flat namespace. Import from the subpackage: from coremusic.audio import
AudioFile.
ImportError from a .so file - the Cython extension is missing or built
for another Python version. In a checkout, rebuild with make build.
See Also¶
- Migration Guide - updating code written for older versions
- API Reference - the classes themselves
- Quick Start - a five-minute tour