Last active
December 18, 2019 15:38
-
-
Save McSinyx/dfbc8fe8ac88e58e292eb50f8e19d2af to your computer and use it in GitHub Desktop.
Alure play in Cython
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Aliases for relevant STL containers not declarable in Cython | |
// Copyright (C) 2019 Nguyễn Gia Phong | |
// | |
// This file is part of archaicy. | |
// | |
// archaicy is free software: you can redistribute it and/or modify it | |
// under the terms of the GNU Lesser General Public License as published | |
// by the Free Software Foundation, either version 3 of the License, | |
// or (at your option) any later version. | |
// | |
// archaicy is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
// GNU Lesser General Public License for more details. | |
// | |
// You should have received a copy of the GNU Lesser General Public License | |
// along with archaicy. If not, see <https://www.gnu.org/licenses/>. | |
#ifndef ARCHAICY_ALIASES_H | |
#define ARCHAICY_ALIASES_H | |
#include <tuple> | |
using BoolTuple3 = std::tuple<bool, bool, bool>; | |
#endif // ARCHAICY_ALIASES_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Cython declarations of alure | |
# Copyright (C) 2019 Nguyễn Gia Phong | |
# | |
# This file is part of archaicy. | |
# | |
# archaicy is free software: you can redistribute it and/or modify it | |
# under the terms of the GNU Lesser General Public License as published | |
# by the Free Software Foundation, either version 3 of the License, | |
# or (at your option) any later version. | |
# | |
# archaicy is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU Lesser General Public License for more details. | |
# | |
# You should have received a copy of the GNU Lesser General Public License | |
# along with archaicy. If not, see <https://www.gnu.org/licenses/>. | |
from libc.stdint cimport uint64_t | |
from libcpp cimport bool, nullptr_t | |
from libcpp.memory cimport shared_ptr | |
from libcpp.pair cimport pair | |
from libcpp.string cimport string | |
from libcpp.vector cimport vector | |
cdef extern from '<future>' namespace 'std' nogil: | |
cdef cppclass shared_future[R]: | |
pass | |
cdef extern from 'archaicy-aliases.h' namespace 'std' nogil: | |
cdef cppclass BoolTuple3: | |
pass | |
cdef extern from '<AL/alure2.h>' namespace 'alure' nogil: | |
# Type aliases: | |
# char*: string | |
# ALfloat: float | |
# ALsizei: int | |
# ALuint: unsigned | |
# Vector: vector | |
# ArrayView: vector | |
# String: string | |
# StringView: string | |
# SharedPtr: shared_ptr | |
# SharedFuture: shared_future | |
# Structs: | |
cdef cppclass AttributePair: | |
pass | |
cdef cppclass FilterParams: | |
pass | |
cdef cppclass SourceSend: | |
pass | |
# Enum classes: | |
cdef cppclass SampleType: | |
pass | |
# The following relies on C++ implicit conversion from char* to string. | |
cdef const string get_sample_type_name 'GetSampleTypeName'(SampleType) except + | |
cdef cppclass ChannelConfig: | |
pass | |
cdef const string get_channel_config_name 'GetChannelConfigName'(ChannelConfig) except + | |
cdef unsigned frames_to_bytes 'FramesToBytes'(unsigned, ChannelConfig, SampleType) except + | |
cdef unsigned bytes_to_frames 'BytesToFrames'(unsigned, ChannelConfig, SampleType) | |
cdef cppclass DeviceEnumeration: | |
pass | |
cdef cppclass DefaultDeviceType: | |
pass | |
cdef cppclass PlaybackName: | |
pass | |
cdef cppclass DistanceModel: | |
pass | |
cdef cppclass Spatialize: | |
pass | |
# Helper classes | |
cdef cppclass Vector3: | |
pass | |
cdef cppclass Version: | |
pass | |
# Opaque class implementations: | |
cdef cppclass DeviceManagerImpl: | |
pass | |
cdef cppclass DeviceImpl: | |
pass | |
cdef cppclass ContextImpl: | |
pass | |
cdef cppclass ListenerImpl: | |
pass | |
cdef cppclass BufferImpl: | |
pass | |
cdef cppclass SourceImpl: | |
pass | |
cdef cppclass SourceGroupImpl: | |
pass | |
cdef cppclass AuxiliaryEffectSlotImpl: | |
pass | |
cdef cppclass EffectImpl: | |
pass | |
# Available class interfaces: | |
cdef cppclass DeviceManager: | |
@staticmethod | |
DeviceManager get_instance 'getInstance'() except + | |
DeviceManager() | |
DeviceManager(const DeviceManager&) | |
DeviceManager(DeviceManager&&) | |
DeviceManager& operator=(const DeviceManager&) | |
DeviceManager& operator=(DeviceManager&&) | |
DeviceManager& operator=(nullptr_t) | |
bool operator bool() | |
bool query_extension 'queryExtension'(const string&) except + | |
vector[string] enumerate(DeviceEnumeration) except + | |
string defaultDeviceName(DefaultDeviceType) except + | |
Device open_playback 'openPlayback'() except + | |
Device open_playback 'openPlayback'(const string&) except + | |
cdef cppclass Device: | |
ctypedef DeviceImpl* handle_type | |
Device() | |
Device(DeviceImpl*) | |
Device(const Device&) | |
Device(Device&&) | |
Device& operator=(const Device&) | |
Device& operator=(Device&&) | |
bool operator==(const Device&) | |
bool operator!=(const Device&) | |
bool operator<=(const Device&) | |
bool operator>=(const Device&) | |
bool operator<(const Device&) | |
bool operator>(const Device&) | |
bool operator bool() | |
handle_type get_handle 'getHandle'() | |
string get_name 'getName'() except + | |
string get_name 'getName'(PlaybackName) except + | |
bool query_extension 'queryExtension'(const string&) except + | |
Version get_alc_version 'getALCVersion'() except + | |
Version get_efx_version 'getEFXVersion'() except + | |
unsigned get_frequency 'getFrequency'() except + | |
unsigned get_max_auxiliary_sends 'getMaxAuxiliarySends'() except + | |
vector[string] enumerate_hrtf_names 'enumerateHRTFNames'() except + | |
bool is_hftf_enable 'isHRTFEnable'() except + | |
string get_current_hrtf 'getCurrentHRTF'() except + | |
void reset(vector[AttributePair]) except + | |
Context create_context 'createContext'() except + | |
Context create_context 'createContext'(vector[AttributePair]) except + | |
void pause_dsp 'pauseDSP'() except + | |
void resume_dsp 'resumeDSP'() except + | |
# get_clock_time | |
void close() except + | |
cdef cppclass Context: | |
ctypedef ContextImpl* handle_type | |
Context() | |
Context(ContextImpl*) | |
Context(const Context&) | |
Context(Context&&) | |
Context& operator=(const Context&) | |
Context& operator=(Context&&) | |
bool operator==(const Context&) | |
bool operator!=(const Context&) | |
bool operator<=(const Context&) | |
bool operator>=(const Context&) | |
bool operator<(const Context&) | |
bool operator>(const Context&) | |
bool operator bool() | |
handle_type get_handle 'getHandle'() | |
@staticmethod | |
void make_current 'MakeCurrent'(Context) except + | |
@staticmethod | |
Context get_current 'GetCurrent'() except + | |
@staticmethod | |
void make_thread_current 'MakeThreadCurrent'(Context) except + | |
@staticmethod | |
Context get_thread_current 'GetThreadCurrent'() except + | |
void destroy() except + | |
Device get_device 'getDevice'() except + | |
void start_batch 'startBatch'() except + | |
void end_batch 'endBatch'() except + | |
Listener get_listener 'getListener'() except + | |
shared_ptr[MessageHandler] set_message_handler 'setMessageHandler'(shared_ptr[MessageHandler]) except + | |
shared_ptr[MessageHandler] get_message_handler 'getMessageHandler'() except + | |
# set_async_wake_interval | |
# get_async_wake_interval | |
shared_ptr[Decoder] create_decoder 'createDecoder'(string) except + | |
bool is_supported 'isSupported'(ChannelConfig, SampleType) except + | |
vector[string] get_available_resamplers 'getAvailableResamplers'() except + | |
int get_default_resampler_index 'getDefaultResamplerIndex'() except + | |
Buffer get_buffer 'getBuffer'(string) except + | |
shared_future[Buffer] get_buffer_async 'getBufferAsync'(string) except + | |
void precache_buffers_async 'precacheBuffersAsync'(vector[string]) except + | |
Buffer create_buffer_from 'createBufferFrom'(string, shared_ptr[Decoder]) except + | |
shared_future[Buffer] create_buffer_async_from 'createBufferAsyncFrom'(string, shared_ptr[Decoder]) except + | |
Buffer find_buffer 'findBuffer'(string) except + | |
shared_future[Buffer] find_buffer_async 'findBufferAsync'(string) except + | |
void remove_buffer 'removeBuffer'(string) except + | |
void remove_buffer 'removeBuffer'(Buffer) except + | |
Source create_source 'createSource'() except + | |
AuxiliaryEffectSlot create_auxiliary_effect_slot 'createAuxiliaryEffectSlot'() except + | |
Effect create_effect 'createEffect'() except + | |
SourceGroup create_source_group 'createSourceGroup'() except + | |
void set_doppler_factor 'setDopplerFactor'(float) except + | |
void set_speed_of_sound 'setSpeedOfSound'(float) except + | |
void set_distance_model 'setDistanceModel'(DistanceModel) except + | |
void update() except + | |
cdef cppclass Listener: | |
pass | |
cdef cppclass Buffer: | |
ctypedef BufferImpl* handle_type | |
Buffer() | |
Buffer(BufferImpl*) | |
Buffer(const Buffer&) | |
Buffer(Buffer&&) | |
Buffer& operator=(const Buffer&) | |
Buffer& operator=(Buffer&&) | |
bool operator==(const Buffer&) | |
bool operator!=(const Buffer&) | |
bool operator<=(const Buffer&) | |
bool operator>=(const Buffer&) | |
bool operator<(const Buffer&) | |
bool operator>(const Buffer&) | |
bool operator bool() | |
handle_type get_handle 'getHandle'() | |
unsigned get_length 'getLength'() except + | |
unsigned get_frequency 'getFrequency'() except + | |
ChannelConfig get_channel_config 'getChannelConfig'() except + | |
SampleType get_sample_type 'getSampleType'() except + | |
unsigned get_size 'getSize'() except + | |
string get_name 'getName'() except + | |
size_t get_source_count 'getSourceCount'() except + | |
vector[Source] get_sources 'getSources'() except + | |
pair[unsigned, unsigned] get_loop_points 'getLoopPoints'() except + | |
void set_loop_points 'setLoopPoints'(unsigned, unsigned) except + | |
cdef cppclass Source: | |
ctypedef SourceImpl* handle_type | |
Source() | |
Source(SourceImpl*) | |
Source(const Source&) | |
Source(Source&&) | |
Source& operator=(const Source&) | |
Source& operator=(Source&&) | |
bool operator==(const Source&) | |
bool operator!=(const Source&) | |
bool operator<=(const Source&) | |
bool operator>=(const Source&) | |
bool operator<(const Source&) | |
bool operator>(const Source&) | |
bool operator bool() | |
handle_type get_handle 'getHandle'() | |
void play(Buffer) except + | |
void play(shared_ptr[Decoder], int, int) except + | |
void play(shared_future[Buffer]) except + | |
void stop() except + | |
# fade_out_to_stop | |
void pause() except + | |
void resume() except + | |
bool is_pending 'isPending'() except + | |
bool is_playing 'isPlaying'() except + | |
bool is_paused 'isPaused'() except + | |
bool is_playing_or_pending 'isPlayingOrPending'() except + | |
void set_group 'setGroup'(SourceGroup) except + | |
SourceGroup get_group 'getGroup'() except + | |
void set_priority 'setPriority'(unsigned) except + | |
unsigned get_priority 'getPriority'() except + | |
void set_offset 'setOffset'(uint64_t) except + | |
# get_sample_offset_latency | |
uint64_t get_sample_offset 'getSampleOffset'() except + | |
uint64_t get_offset 'getOffset'() except + | |
# get_sec_offset_latency | |
# get_sec_offset | |
void set_looping 'setLooping'(bool) except + | |
bool get_looping 'getLooping'() except + | |
void set_pitch 'setPitch'(float) except + | |
float get_pitch 'getPitch'() except + | |
void set_gain 'setGain'(float) except + | |
float get_gain 'getGain'() except + | |
void set_gain_range 'setGainRange'(float, float) except + | |
pair[float, float] get_gain_range 'getGainRange'() except + | |
float get_min_gain 'getMinGain'() except + | |
float get_max_gain 'getMaxGain'() except + | |
void set_distance_range 'setDistanceRange'(float, float) except + | |
pair[float, float] get_distance_range 'getDistanceRange'() except + | |
float get_reference_distance 'getReferenceDistance'() except + | |
float get_max_distance 'getMaxDistance'() except + | |
void set_3d_parameters 'set3DParameters'(const Vector3&, const Vector3&, const Vector3&) except + | |
void set_3d_parameters 'set3DParameters'(const Vector3&, const Vector3&, const pair[Vector3, Vector3]&) except + | |
void set_position 'setPosition'(const Vector3&) except + | |
void set_position 'setPosition'(const float*) except + | |
Vector3 get_position 'getPosition'() except + | |
void set_velocity 'setVelocity'(const Vector3&) except + | |
void set_velocity 'setVelocity'(const float*) except + | |
Vector3 get_velocity 'getVelocity'() except + | |
void set_direction 'setDirection'(const Vector3&) except + | |
void set_direction 'setDirection'(const float*) except + | |
Vector3 get_direction 'getDirection'() except + | |
void set_orientation 'setOrientation'(const pair[Vector3, Vector3]&) except + | |
void set_orientation 'setOrientation'(const float*, const float*) except + | |
void set_orientation 'setOrientation'(const float*) except + | |
pair[Vector3, Vector3] get_orientation 'getOrientation'() except + | |
void set_cone_angles 'setConeAngles'(float, float) except + | |
pair[float, float] get_cone_angles 'getConeAngles'() except + | |
float get_inner_cone_angle 'getInnerConeAngle'() except + | |
float get_outer_cone_angle 'getOuterConeAngle'() except + | |
void set_outer_cone_gains 'setOuterConeGains'(float) except + | |
void set_outer_cone_gains 'setOuterConeGains'(float, float) except + | |
pair[float, float] get_outer_cone_gains 'getOuterConeGains'() except + | |
float get_outer_cone_gain 'getOuterConeGain'() except + | |
float get_outer_cone_gainhf 'getOuterConeGainHF'() except + | |
void set_rolloff_factors 'setRolloffFactors'(float) except + | |
void set_rolloff_factors 'setRolloffFactors'(float, float) except + | |
pair[float, float] get_rolloff_factors 'getRolloffFactors'() except + | |
float get_rolloff_factor 'getRolloffFactor'() except + | |
float get_room_rolloff_factor 'getRoomRolloffFactor'() except + | |
void set_doppler_factor 'setDopplerFactor'(float) except + | |
float set_doppler_factor 'getDopplerFactor'() except + | |
void set_relative 'setRelative'(bool) except + | |
bool get_relative 'getRelative'() except + | |
void set_radius 'setRadius'(float) except + | |
float get_radius 'getRadius'() except + | |
void set_stereo_angles 'setStereoAngles'(float, float) except + | |
pair[float, float] get_stereo_angles 'getStereoAngles'() except + | |
void set_3d_spatialize 'set3DSpatialize'(Spatialize) except + | |
Spatialize get_3d_spatialize 'get3DSpatialize'() except + | |
void set_resampler_index 'setResamplerIndex'(int) except + | |
int get_resampler_index 'getResamplerIndex'() except + | |
void set_air_absorption_factor 'setAirAbsorptionFactor'(float) except + | |
float get_air_absorption_factor 'getAirAbsorptionFactor'() except + | |
void set_gain_auto 'setGainAuto'(bool, bool, bool) except + | |
BoolTuple3 get_gain_auto 'getGainAuto'() except + | |
bool get_direct_gain_hf_auto 'getDirectGainHFAuto'() except + | |
bool get_send_gain_auto 'getSendGainAuto'() except + | |
bool get_send_gain_hf_auto 'getSendGainHFAuto'() except + | |
void set_direct_filter 'setDirectFilter'(const FilterParams&) except + | |
void set_send_filter 'setSendFilter'(unsigned, const FilterParams&) except + | |
void set_auxiliary_send 'setAuxiliarySend'(AuxiliaryEffectSlot, int) except + | |
void set_auxiliary_send_filter 'setAuxiliarySendFilter'(AuxiliaryEffectSlot, int, const FilterParams&) except + | |
void destroy() except + | |
cdef cppclass SourceGroup: | |
pass | |
cdef cppclass AuxiliaryEffectSlot: | |
pass | |
cdef cppclass Effect: | |
pass | |
cdef cppclass Decoder: | |
pass | |
cdef cppclass DecoderFactory: | |
pass | |
cdef cppclass FileIOFactory: | |
pass | |
cdef cppclass MessageHandler: | |
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from time import sleep | |
from typing import Iterable | |
from libcpp cimport nullptr | |
from archaicy cimport (get_sample_type_name, get_channel_config_name, | |
DeviceManager, Context) | |
def play(files: Iterable[bytes], device: bytes = None): | |
devmgr = DeviceManager.get_instance() | |
if device is not None: | |
dev = devmgr.open_playback(device) | |
else: | |
dev = devmgr.open_playback() | |
print(f'Opened "{dev.get_name().decode()}"') | |
ctx = dev.create_context() | |
Context.make_current(ctx) | |
for filename in files: | |
buffer = ctx.get_buffer(filename) | |
source = ctx.create_source() | |
source.play(buffer) | |
print('Playing {}, ({}, {}, {}hz)'.format( | |
filename.decode(), | |
get_sample_type_name(buffer.get_sample_type()).decode(), | |
get_channel_config_name(buffer.get_channel_config()).decode(), | |
buffer.get_frequency())) | |
while (source.is_playing()): | |
print(f' {source.get_sample_offset()} / {buffer.get_length()}', | |
end='\r', flush=True) | |
sleep(0.025) | |
print() | |
source.destroy() | |
ctx.remove_buffer(buffer) | |
Context.make_current(<Context> nullptr) | |
ctx.destroy() | |
dev.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from Cython.Build import cythonize | |
from setuptools import setup, Extension | |
play = Extension('play', ['play.pyx'], | |
include_dirs=['/usr/include/AL/'], | |
libraries=['alure2'], | |
language='c++') | |
setup(ext_modules=cythonize(play, compiler_directives={'language_level': 3}), | |
zip_safe=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment