1
1
Fork 0
mirror of https://github.com/McSinyx/palace synced 2023-12-14 09:02:59 +01:00

Move utilities to native C++

This commit is contained in:
Nguyễn Gia Phong 2020-03-31 11:35:09 +07:00
parent 47231e9992
commit e747159161
5 changed files with 118 additions and 118 deletions

View file

@ -62,15 +62,14 @@ class BuildAlure2Ext(build_ext):
class CleanCppToo(clean):
"""Clean command that remove Cython C++ outputs."""
def run(self) -> None:
"""Remove Cython C++ outputs on `setup.py clean --all`."""
if self.all:
for cpp in [join('src', 'palace.cpp')]:
log.info(f'removing {cpp!r}')
try:
unlink(cpp)
except OSError as e:
raise DistutilsFileError(
f'could not delete {cpp!r}: {e.strerror}')
"""Remove Cython C++ outputs on clean command."""
for cpp in [join('src', 'palace.cpp')]:
log.info(f'removing {cpp!r}')
try:
unlink(cpp)
except OSError as e:
raise DistutilsFileError(
f'could not delete {cpp!r}: {e.strerror}')
super().run()

View file

@ -20,7 +20,6 @@
from libc.stdint cimport int64_t, uint64_t
from libcpp cimport bool as boolean, nullptr_t
from libcpp.unordered_map cimport unordered_map
from libcpp.memory cimport shared_ptr, unique_ptr
from libcpp.string cimport string
from libcpp.utility cimport pair
@ -69,11 +68,6 @@ cdef extern from 'alure2-alext.h' nogil:
cdef int ALC_OUTPUT_LIMITER_SOFT
cdef extern from 'efx-predef.h' namespace 'palace' nogil:
cdef const unordered_map[string, EFXEAXREVERBPROPERTIES] REVERB_PRESETS
cdef vector[string] reverb_preset_names() except +
cdef extern from 'alure2-aliases.h' namespace 'alure' nogil:
ctypedef duration[double] Seconds
@ -139,9 +133,7 @@ cdef extern from 'alure2.h' namespace 'alure' nogil:
# Structs:
cdef cppclass AttributePair:
int attribute 'mAttribute'
int value 'mValue'
pass
cdef cppclass FilterParams:
pass
@ -151,21 +143,9 @@ cdef extern from 'alure2.h' namespace 'alure' nogil:
# Enum classes:
cdef enum SampleType:
UInt8 'alure::SampleType::UInt8' # Unsigned 8-bit
Int16 'alure::SampleType::Int16' # Signed 16-bit
Float32 'alure::SampleType::Float32' # 32-bit float
Mulaw 'alure::SampleType::Mulaw' # Mulaw
pass
cdef enum ChannelConfig:
Mono 'alure::ChannelConfig::Mono' # Mono
Stereo 'alure::ChannelConfig::Stereo' # Stereo
Rear 'alure::ChannelConfig::Rear' # Rear
Quad 'alure::ChannelConfig::Quad' # Quadrophonic
X51 'alure::ChannelConfig::X51' # 5.1 Surround
X61 'alure::ChannelConfig::X61' # 6.1 Surround
X71 'alure::ChannelConfig::X71' # 7.1 Surround
BFormat2D 'alure::ChannelConfig::BFormat2D' # B-Format 2D
BFormat3D 'alure::ChannelConfig::BFormat3D' # B-Format 3D
pass
# The following relies on C++ implicit conversion from char* to string.
cdef const string get_sample_type_name 'GetSampleTypeName'(SampleType) except +

View file

@ -54,7 +54,7 @@ channel_configs : Tuple[str, ...]
device_names : DeviceNames
Read-only namespace of device names by category (basic, full and
capture), as tuples of strings whose first item being the default.
device_names : Tuple[str]
reverb_preset_names : Tuple[str]
Names of predefined reverb effect presets in lexicographical order.
decoder_factories : DecoderNamespace
Simple object for storing decoder factories.
@ -112,6 +112,8 @@ from cpython.ref cimport Py_INCREF, Py_DECREF
from cython.operator cimport dereference as deref
cimport alure # noqa
from util cimport (REVERB_PRESETS, SAMPLE_TYPES, CHANNEL_CONFIGS, # noqa
reverb_presets, mkattrs, from_vector3, to_vector3)
# Aliases
@ -165,7 +167,7 @@ cdef alure.DeviceManager devmgr = alure.DeviceManager.get_instance()
device_names: DeviceNames = DeviceNames()
cdef boolean _thread = False
reverb_preset_names: Tuple[str] = tuple(sorted(alure.reverb_preset_names()))
reverb_preset_names: Tuple[str] = tuple(reverb_presets())
decoder_factories: DecoderNamespace = DecoderNamespace()
cdef object fileio_factory = None # type: Optional[Callable[[str], FileIO]]
@ -178,14 +180,22 @@ def sample_size(length: int, channel_config: str, sample_type: str) -> int:
RuntimeError
If the byte size result too large.
"""
return alure.frames_to_bytes(
length, to_channel_config(channel_config), to_sample_type(sample_type))
try:
return alure.frames_to_bytes(length,
CHANNEL_CONFIGS.at(channel_config),
SAMPLE_TYPES.at(sample_type))
except IndexError as e:
raise ValueError(str(e))
def sample_length(size: int, channel_config: str, sample_type: str) -> int:
"""Return the number of frames stored in the given byte size."""
return alure.bytes_to_frames(
size, to_channel_config(channel_config), to_sample_type(sample_type))
try:
return alure.bytes_to_frames(size,
CHANNEL_CONFIGS.at(channel_config),
SAMPLE_TYPES.at(sample_type))
except IndexError as e:
raise ValueError(str(e))
def query_extension(name: str) -> bool:
@ -675,8 +685,11 @@ cdef class Context:
sample_types : Set of sample types
channel_configs : Set of channel configurations
"""
return self.impl.is_supported(to_channel_config(channel_config),
to_sample_type(sample_type))
try:
return self.impl.is_supported(CHANNEL_CONFIGS.at(channel_config),
SAMPLE_TYPES.at(sample_type))
except IndexError as e:
raise ValueError(str(e))
@getter
def available_resamplers(self) -> List[str]:
@ -2017,7 +2030,7 @@ cdef class Effect:
If set to a preset cannot be found in `reverb_preset_names`.
"""
try:
self.impl.set_reverb_properties(alure.REVERB_PRESETS.at(value))
self.impl.set_reverb_properties(REVERB_PRESETS.at(value))
except IndexError:
raise ValueError(f'Invalid preset name: {value}')
@ -2268,7 +2281,6 @@ cdef class Decoder:
(<Source> source).impl.play(self.pimpl, chunk_len, queue_size)
# Decoder interface
cdef class _BaseDecoder(Decoder):
"""Cython bridge for BaseDecoder.
@ -2365,10 +2377,10 @@ cdef cppclass CppDecoder(alure.BaseDecoder):
return pyo.frequency
alure.ChannelConfig get_channel_config_() const:
return to_channel_config(pyo.channel_config)
return CHANNEL_CONFIGS.at(pyo.channel_config)
alure.SampleType get_sample_type_() const:
return to_sample_type(pyo.sample_type)
return SAMPLE_TYPES.at(pyo.sample_type)
uint64_t get_length_() const:
return pyo.length
@ -2597,65 +2609,3 @@ cdef cppclass CppMessageHandler(alure.BaseMessageHandler):
string resource_not_found(string name):
return pyo.resource_not_found(name)
# Helper cdef functions
cdef vector[alure.AttributePair] mkattrs(vector[pair[int, int]] attrs):
"""Convert attribute pairs from Python object to alure format."""
cdef vector[alure.AttributePair] attributes
cdef alure.AttributePair pair
for attribute, value in attrs:
pair.attribute = attribute
pair.value = value
attributes.push_back(pair) # insert a copy
pair.attribute = pair.value = 0
attributes.push_back(pair) # insert a copy
return attributes
cdef vector[float] from_vector3(alure.Vector3 v):
"""Convert alure::Vector3 to std::vector of 3 floats."""
cdef vector[float] result
for i in range(3): result.push_back(v[i])
return result
cdef alure.Vector3 to_vector3(vector[float] v):
"""Convert std::vector of 3 floats to alure::Vector3."""
return alure.Vector3(v[0], v[1], v[2])
cdef alure.SampleType to_sample_type(str name) except +:
"""Return the specified sample type enumeration."""
if name == 'Unsigned 8-bit':
return alure.SampleType.UInt8
elif name == 'Signed 16-bit':
return alure.SampleType.Int16
elif name == '32-bit float':
return alure.SampleType.Float32
elif name == 'Mulaw':
return alure.SampleType.Mulaw
raise ValueError(f'Invalid sample type name: {name}')
cdef alure.ChannelConfig to_channel_config(str name) except +:
"""Return the specified channel configuration enumeration."""
if name == 'Mono':
return alure.ChannelConfig.Mono
elif name == 'Stereo':
return alure.ChannelConfig.Stereo
elif name == 'Rear':
return alure.ChannelConfig.Rear
elif name == 'Quadrophonic':
return alure.ChannelConfig.Quad
elif name == '5.1 Surround':
return alure.ChannelConfig.X51
elif name == '6.1 Surround':
return alure.ChannelConfig.X61
elif name == '7.1 Surround':
return alure.ChannelConfig.X71
elif name == 'B-Format 2D':
return alure.ChannelConfig.BFormat2D
elif name == 'B-Format 3D':
return alure.ChannelConfig.BFormat3D
raise ValueError(f'Invalid channel configuration name: {name}')

View file

@ -1,4 +1,4 @@
// Predefined environmental effects
// Helper functions and mapping
// Copyright (C) 2020 Nguyễn Gia Phong
//
// This file is part of palace.
@ -16,20 +16,39 @@
// You should have received a copy of the GNU Lesser General Public License
// along with palace. If not, see <https://www.gnu.org/licenses/>.
#ifndef PALACE_PREDEF_H
#define PALACE_PREDEF_H
#ifndef PALACE_UTIL_H
#define PALACE_UTIL_H
#include <string>
#include <unordered_map>
#include <map>
#include <utility>
#include <vector>
#include "alure2.h"
#include "efx-presets.h"
#define DECL(x) { #x, EFX_REVERB_PRESET_##x }
namespace palace
{
const std::map<std::string, alure::SampleType> SAMPLE_TYPES {
{"Unsigned 8-bit", alure::SampleType::UInt8},
{"Signed 16-bit", alure::SampleType::Int16},
{"32-bit float", alure::SampleType::Float32},
{"Mulaw", alure::SampleType::Mulaw}};
const std::map<std::string, alure::ChannelConfig> CHANNEL_CONFIGS {
{"Mono", alure::ChannelConfig::Mono},
{"Stereo", alure::ChannelConfig::Stereo},
{"Rear", alure::ChannelConfig::Rear},
{"Quadrophonic", alure::ChannelConfig::Quad},
{"5.1 Surround", alure::ChannelConfig::X51},
{"6.1 Surround", alure::ChannelConfig::X61},
{"7.1 Surround", alure::ChannelConfig::X71},
{"B-Format 2D", alure::ChannelConfig::BFormat2D},
{"B-Format 3D", alure::ChannelConfig::BFormat3D}};
// This is ported from alure-reverb example.
const std::unordered_map<std::string, EFXEAXREVERBPROPERTIES> REVERB_PRESETS {
#define DECL(x) { #x, EFX_REVERB_PRESET_##x }
const std::map<std::string, EFXEAXREVERBPROPERTIES> REVERB_PRESETS {
DECL(GENERIC), DECL(PADDEDCELL), DECL(ROOM), DECL(BATHROOM),
DECL(LIVINGROOM), DECL(STONEROOM), DECL(AUDITORIUM), DECL(CONCERTHALL),
DECL(CAVE), DECL(ARENA), DECL(HANGAR), DECL(CARPETEDHALLWAY), DECL(HALLWAY),
@ -83,18 +102,35 @@ namespace palace
DECL(CITY_STREETS), DECL(CITY_SUBWAY), DECL(CITY_MUSEUM),
DECL(CITY_LIBRARY), DECL(CITY_UNDERPASS), DECL(CITY_ABANDONED),
DECL(DUSTYROOM), DECL(CHAPEL), DECL(SMALLWATERROOM),
};
DECL(DUSTYROOM), DECL(CHAPEL), DECL(SMALLWATERROOM)};
#undef DECL
inline std::vector<std::string>
reverb_preset_names()
reverb_presets() noexcept
{
std::vector<std::string> presets;
for (auto const& preset : REVERB_PRESETS)
presets.push_back (preset.first);
return presets;
}
} // namespace palace
#undef DECL
#endif // PALACE_PREDEF_H
inline std::vector<alure::AttributePair>
mkattrs (std::vector<std::pair<int, int>> attrs) noexcept
{
std::vector<alure::AttributePair> attributes;
for (auto const& pair : attrs)
attributes.push_back ({pair.first, pair.second});
attributes.push_back (alure::AttributesEnd());
return attributes;
}
inline std::vector<float>
from_vector3 (alure::Vector3 v) noexcept
{ return std::vector<float> {v[0], v[1], v[2]}; }
inline alure::Vector3
to_vector3 (std::vector<float> v) noexcept
{ return alure::Vector3 (v[0], v[1], v[2]); }
} // namespace palace
#endif // PALACE_UTIL_H

35
src/util.pxd Normal file
View file

@ -0,0 +1,35 @@
# Helper functions and mapping
# Copyright (C) 2020 Nguyễn Gia Phong
#
# This file is part of palace.
#
# palace 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.
#
# palace 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 palace. If not, see <https://www.gnu.org/licenses/>.
from libcpp.map cimport map
from libcpp.string cimport string
from libcpp.utility cimport pair
from libcpp.vector cimport vector
from alure cimport (AttributePair, EFXEAXREVERBPROPERTIES, # noqa
ChannelConfig, SampleType, Vector3)
cdef extern from 'util.h' namespace 'palace' nogil:
cdef const map[string, EFXEAXREVERBPROPERTIES] REVERB_PRESETS
cdef const map[string, SampleType] SAMPLE_TYPES
cdef const map[string, ChannelConfig] CHANNEL_CONFIGS
cdef vector[string] reverb_presets()
cdef vector[AttributePair] mkattrs(vector[pair[int, int]])
cdef vector[float] from_vector3(Vector3)
cdef Vector3 to_vector3(vector[float])