Added basic play feature for the audio buffer
This commit is contained in:
parent
abfb232cab
commit
8162c463b4
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import widgetUtils
|
||||
import messages
|
||||
import player
|
||||
import utils
|
||||
from wxUI.tabs import home
|
||||
from pubsub import pub
|
||||
@ -70,3 +71,13 @@ class feedBuffer(baseBuffer):
|
||||
class audioBuffer(feedBuffer):
|
||||
def create_tab(self, parent):
|
||||
self.tab = home.audioTab(parent)
|
||||
|
||||
def connect_events(self):
|
||||
widgetUtils.connect_event(self.tab.post, widgetUtils.BUTTON_PRESSED, self.post)
|
||||
widgetUtils.connect_event(self.tab.play, widgetUtils.BUTTON_PRESSED, self.play_audio)
|
||||
|
||||
def play_audio(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_selected()
|
||||
player.player.play(self.session.db[self.name]["items"][selected]["url"])
|
||||
|
||||
player.setup()
|
@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import widgetUtils
|
||||
import messages
|
||||
from wxUI import (mainWindow)
|
||||
import buffers
|
||||
from pubsub import pub
|
||||
from mysc.repeating_timer import RepeatingTimer
|
||||
from sessionmanager import session
|
||||
from wxUI import (mainWindow)
|
||||
|
||||
class Controller(object):
|
||||
|
||||
|
46
src/controller/player.py
Normal file
46
src/controller/player.py
Normal file
@ -0,0 +1,46 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sound_lib
|
||||
from sound_lib.output import Output
|
||||
from sound_lib.stream import URLStream
|
||||
|
||||
player = None
|
||||
|
||||
def setup():
|
||||
global player
|
||||
if player == None:
|
||||
player = audioPlayer()
|
||||
|
||||
class audioPlayer(object):
|
||||
|
||||
def __init__(self):
|
||||
Output()
|
||||
self.is_playing = False
|
||||
self.stream = None
|
||||
self.vol = 100
|
||||
|
||||
def play(self, url):
|
||||
if self.stream != None and self.stream.is_playing == True:
|
||||
self.stream.stop()
|
||||
self.stream = URLStream(url=url)
|
||||
self.stream.volume = self.vol/100.0
|
||||
self.stream.play()
|
||||
|
||||
def stop(self):
|
||||
if self.stream != None and self.stream.is_playing == True:
|
||||
self.stream.stop()
|
||||
|
||||
def pause(self):
|
||||
if self.stream != None and self.stream.is_playing == True:
|
||||
self.stream.pause()
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
if self.stream != None:
|
||||
return self.vol
|
||||
|
||||
@volume.setter
|
||||
def volume(self, vol):
|
||||
self.vol = vol
|
||||
if self.stream != None:
|
||||
self.stream.volume = vol/100.0
|
||||
|
25
src/sound_lib/__init__.py
Normal file
25
src/sound_lib/__init__.py
Normal file
@ -0,0 +1,25 @@
|
||||
import output, input, recording, stream
|
||||
|
||||
__author__ = 'Christopher Toth'
|
||||
__version__ = 0.73
|
||||
|
||||
def find_datafiles():
|
||||
from glob import glob
|
||||
import os
|
||||
import platform
|
||||
import sound_lib
|
||||
path = os.path.join(sound_lib.__path__[0], 'lib')
|
||||
system = platform.system()
|
||||
if system == 'Windows':
|
||||
file_ext = '*.dll'
|
||||
elif system == 'Darwin':
|
||||
file_ext = '*.dylib'
|
||||
else:
|
||||
file_ext = '*.so'
|
||||
if platform.architecture()[0] == '32bit' or platform.system() == 'Darwin':
|
||||
arch = 'x86'
|
||||
else:
|
||||
arch = 'x64'
|
||||
dest_dir = os.path.join('sound_lib', 'lib', arch)
|
||||
source = glob(os.path.join(path, arch, file_ext))
|
||||
return [(dest_dir, source)]
|
285
src/sound_lib/channel.py
Normal file
285
src/sound_lib/channel.py
Normal file
@ -0,0 +1,285 @@
|
||||
from __future__ import absolute_import
|
||||
from .external.pybass import *
|
||||
from .main import bass_call, bass_call_0, BassError, update_3d_system, FlagObject
|
||||
from ctypes import pointer, c_float, c_long, c_ulong, c_buffer
|
||||
|
||||
class Channel (FlagObject):
|
||||
"""A "channel" can be a sample playback channel (HCHANNEL), a sample stream (HSTREAM), a MOD music (HMUSIC), or a recording (HRECORD). Each "Channel" function can be used with one or more of these channel types."""
|
||||
|
||||
def __init__ (self, handle):
|
||||
self.handle = handle
|
||||
self.attribute_mapping = {
|
||||
'eaxmix': BASS_ATTRIB_EAXMIX,
|
||||
'frequency': BASS_ATTRIB_FREQ,
|
||||
'pan': BASS_ATTRIB_PAN,
|
||||
'volume': BASS_ATTRIB_VOL
|
||||
}
|
||||
|
||||
def add_attributes_to_mapping(self, **attrs):
|
||||
self.attribute_mapping.update(**attrs)
|
||||
|
||||
def play (self, restart=False):
|
||||
"""Starts (or resumes) playback of a sample, stream, MOD music, or recording."""
|
||||
return bass_call(BASS_ChannelPlay, self.handle, restart)
|
||||
|
||||
def play_blocking(self, restart=False):
|
||||
self.play(restart=restart)
|
||||
while self.is_playing:
|
||||
pass
|
||||
|
||||
def pause (self):
|
||||
return bass_call(BASS_ChannelPause, self.handle)
|
||||
|
||||
def is_active (self):
|
||||
"Checks if a sample, stream, or MOD music is active (playing) or stalled. Can also check if a recording is in progress."""
|
||||
return bass_call_0(BASS_ChannelIsActive, self.handle)
|
||||
|
||||
@property
|
||||
def is_playing(self):
|
||||
return self.is_active() == BASS_ACTIVE_PLAYING
|
||||
|
||||
@property
|
||||
def is_paused(self):
|
||||
return self.is_active() == BASS_ACTIVE_PAUSED
|
||||
|
||||
@property
|
||||
def is_stopped(self):
|
||||
return self.is_active() == BASS_ACTIVE_STOPPED
|
||||
|
||||
@property
|
||||
def is_stalled(self):
|
||||
return self.is_active() == BASS_ACTIVE_STALLED
|
||||
|
||||
def get_position (self, mode=BASS_POS_BYTE):
|
||||
"""Retrieves the playback position of a sample, stream, or MOD music. Can also be used with a recording channel."""
|
||||
return bass_call_0(BASS_ChannelGetPosition, self.handle, mode)
|
||||
|
||||
def set_position (self, pos, mode=BASS_POS_BYTE):
|
||||
"""Sets the playback position of a sample, MOD music, or stream."""
|
||||
return bass_call(BASS_ChannelSetPosition, self.handle, pos, mode)
|
||||
|
||||
position = property(get_position, set_position)
|
||||
|
||||
def stop (self):
|
||||
"""Stops a sample, stream, MOD music, or recording."""
|
||||
return bass_call(BASS_ChannelStop, self.handle)
|
||||
|
||||
def update (self, length=0):
|
||||
"""Updates the playback buffer of a stream or MOD music."""
|
||||
return bass_call(BASS_ChannelUpdate, self.handle, length)
|
||||
|
||||
def get_length (self, mode=BASS_POS_BYTE):
|
||||
return bass_call_0(BASS_ChannelGetLength, self.handle, mode)
|
||||
|
||||
__len__ = get_length
|
||||
|
||||
def __bool__(self):
|
||||
return True
|
||||
|
||||
def get_device(self):
|
||||
"""Retrieves the device that a channel is using."""
|
||||
return bass_call_0( BASS_ChannelGetDevice, self.handle)
|
||||
|
||||
def set_device (self, device):
|
||||
"""Changes the device that a stream, MOD music or sample is using."""
|
||||
bass_call(BASS_ChannelSetDevice, self.handle, device)
|
||||
|
||||
device = property(get_device, set_device)
|
||||
|
||||
def set_fx(self, type, priority=0):
|
||||
"""Sets an effect on a stream, MOD music, or recording channel."""
|
||||
return SoundEffect(bass_call(BASS_ChannelSetFX, type, priority))
|
||||
|
||||
def bytes_to_seconds(self, position=None):
|
||||
"""Translates a byte position into time (seconds), based on a channel's format."""
|
||||
position = position or self.position
|
||||
return bass_call_0(BASS_ChannelBytes2Seconds, self.handle, position)
|
||||
|
||||
def length_in_seconds(self):
|
||||
return self.bytes_to_seconds(self.get_length())
|
||||
|
||||
|
||||
def seconds_to_bytes(self, position):
|
||||
"""Translates a time (seconds) position into bytes, based on a channel's format."""
|
||||
return bass_call_0(BASS_ChannelSeconds2Bytes, self.handle, position)
|
||||
|
||||
def get_attribute(self, attribute):
|
||||
"""Retrieves the value of a channel's attribute."""
|
||||
value = pointer(c_float())
|
||||
if attribute in self.attribute_mapping:
|
||||
attribute = self.attribute_mapping[attribute]
|
||||
bass_call(BASS_ChannelGetAttribute, self.handle, attribute, value)
|
||||
return value.contents.value
|
||||
|
||||
def set_attribute(self, attribute, value):
|
||||
"""Sets the value of a channel's attribute."""
|
||||
if attribute in self.attribute_mapping:
|
||||
attribute = self.attribute_mapping[attribute]
|
||||
return bass_call(BASS_ChannelSetAttribute, self.handle, attribute, value)
|
||||
|
||||
def slide_attribute(self, attribute, value, time):
|
||||
"""Slides a channel's attribute from its current value to a new value."""
|
||||
if attribute in self.attribute_mapping:
|
||||
attribute = self.attribute_mapping[attribute]
|
||||
return bass_call(BASS_ChannelSlideAttribute, self.handle, attribute, value, time*1000)
|
||||
|
||||
def is_sliding (self, attribute=None):
|
||||
"""Checks if an attribute (or any attribute) of a sample, stream, or MOD music is sliding."""
|
||||
return bass_call_0(BASS_ChannelIsSliding, self.handle, attribute)
|
||||
|
||||
def get_info(self):
|
||||
"""Retrieves information on a channel."""
|
||||
value = pointer(BASS_CHANNELINFO())
|
||||
bass_call(BASS_ChannelGetInfo, self.handle, value)
|
||||
return value[0]
|
||||
|
||||
def get_level(self):
|
||||
"""Retrieves the level (peak amplitude) of a stream, MOD music or recording channel."""
|
||||
return bass_call_0(BASS_ChannelGetLevel, self.handle)
|
||||
|
||||
def lock(self):
|
||||
"""Locks a stream, MOD music or recording channel to the current thread."""
|
||||
return bass_call(BASS_ChannelLock, self.handle, True)
|
||||
|
||||
def unlock(self):
|
||||
"""Unlocks a stream, MOD music or recording channel from the current thread."""
|
||||
return bass_call(BASS_ChannelLock, self.handle, False)
|
||||
|
||||
def get_3d_attributes(self):
|
||||
"""Retrieves the 3D attributes of a sample, stream, or MOD music channel with 3D functionality."""
|
||||
answer = dict(mode=c_ulong(), min=c_float(), max=c_float(), iangle=c_ulong(), oangle=c_ulong(), outvol=c_float())
|
||||
bass_call(BASS_ChannelGet3DAttributes, self.handle, pointer(answer['mode']), pointer(answer['min']), pointer(answer['max']), pointer(answer['iangle']), pointer(answer['oangle']), pointer(answer['outvol']))
|
||||
for k in answer:
|
||||
answer[k] = answer[k].value()
|
||||
return answer
|
||||
|
||||
@update_3d_system
|
||||
def set_3d_attributes(self, mode=-1, min=0.0, max=0.0, iangle=-1, oangle=-1, outvol=-1):
|
||||
"""Sets the 3D attributes of a sample, stream, or MOD music channel with 3D functionality."""
|
||||
return bass_call(BASS_ChannelSet3DAttributes, self.handle, mode, min, max, iangle, oangle, outvol)
|
||||
|
||||
def get_3d_position(self):
|
||||
"""Retrieves the 3D position of a sample, stream, or MOD music channel with 3D functionality."""
|
||||
answer = dict(position=BASS_3DVECTOR(), orientation=BASS_3DVECTOR(), velocity=BASS_3DVECTOR())
|
||||
bass_call(BASS_ChannelGet3DPosition, self.handle, pointer(answer['position']), pointer(answer['orientation']), pointer(answer['velocity']))
|
||||
return answer
|
||||
|
||||
@update_3d_system
|
||||
def set_3d_position(self, position=None, orientation=None, velocity=None):
|
||||
"""Sets the 3D position of a sample, stream, or MOD music channel with 3D functionality."""
|
||||
if position:
|
||||
position = pointer(position)
|
||||
if orientation:
|
||||
orientation = pointer(orientation)
|
||||
if velocity:
|
||||
velocity = pointer(velocity)
|
||||
return bass_call(BASS_ChannelSet3DPosition, self.handle, position, orientation, velocity)
|
||||
|
||||
def set_link(self, handle):
|
||||
"""Links two MOD music or stream channels together."""
|
||||
bass_call(BASS_ChannelSetLink, self.handle, handle)
|
||||
|
||||
def remove_link(self, handle):
|
||||
"""Removes a link between two MOD music or stream channels."""
|
||||
return bass_call(BASS_ChannelRemoveLink, self.handle, handle)
|
||||
|
||||
def __iadd__(self, other):
|
||||
"""Convenience method to link this channel to another. Calls set_link on the passed in item's handle"""
|
||||
self.set_link(other.handle)
|
||||
return self
|
||||
|
||||
def __isub__(self, other):
|
||||
"""Convenience method to unlink this channel from another. Calls remove_link on the passed in item's handle"""
|
||||
self.remove_link(other.handle)
|
||||
return self
|
||||
|
||||
def get_frequency(self):
|
||||
return self.get_attribute(BASS_ATTRIB_FREQ )
|
||||
|
||||
def set_frequency(self, frequency):
|
||||
self.set_attribute(BASS_ATTRIB_FREQ, frequency)
|
||||
|
||||
frequency = property(fget=get_frequency, fset=set_frequency)
|
||||
|
||||
def get_pan(self):
|
||||
return self.get_attribute(BASS_ATTRIB_PAN)
|
||||
|
||||
def set_pan(self, pan):
|
||||
return self.set_attribute(BASS_ATTRIB_PAN, pan)
|
||||
|
||||
pan = property(fget=get_pan, fset=set_pan)
|
||||
|
||||
def get_volume(self):
|
||||
return self.get_attribute(BASS_ATTRIB_VOL)
|
||||
|
||||
def set_volume(self, volume):
|
||||
self.set_attribute(BASS_ATTRIB_VOL, volume)
|
||||
|
||||
volume = property(fget=get_volume, fset=set_volume)
|
||||
|
||||
def get_data(self, length=16384):
|
||||
buf = c_buffer(length)
|
||||
bass_call_0(BASS_ChannelGetData, self.handle, pointer(buf), length)
|
||||
return buf
|
||||
|
||||
|
||||
#This is less and less of a one-to-one mapping,
|
||||
#But I feel that it's better to be consistent with ourselves
|
||||
#Than with the library. We won't punish ourselves
|
||||
#For their bad decisions
|
||||
|
||||
def get_looping(self):
|
||||
return bass_call_0(BASS_ChannelFlags, self.handle, BASS_SAMPLE_LOOP, 0) == 20
|
||||
|
||||
def set_looping(self, looping):
|
||||
if looping:
|
||||
return bass_call_0(BASS_ChannelFlags, self.handle, BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP)
|
||||
return bass_call_0(BASS_ChannelFlags, self.handle, 0, BASS_SAMPLE_LOOP)
|
||||
|
||||
looping = property(fget=get_looping, fset=set_looping)
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
self.free()
|
||||
except:
|
||||
pass
|
||||
|
||||
def get_x(self):
|
||||
return self.get_3d_position()['position'].x
|
||||
|
||||
def set_x(self, val):
|
||||
pos = self.get_3d_position()
|
||||
pos['position'].x = val
|
||||
self.set_3d_position(**pos)
|
||||
|
||||
x = property(fget=get_x, fset=set_x)
|
||||
|
||||
def get_y(self):
|
||||
return self.get_3d_position()['position'].y
|
||||
|
||||
def set_y(self, val):
|
||||
pos = self.get_3d_position()
|
||||
pos['position'].y = val
|
||||
self.set_3d_position(**pos)
|
||||
|
||||
y = property(fget=get_y, fset=set_y)
|
||||
|
||||
def get_z(self):
|
||||
return self.get_3d_position()['position'].z
|
||||
|
||||
def set_z(self, val):
|
||||
pos = self.get_3d_position()
|
||||
pos['position'].z = val
|
||||
self.set_3d_position(**pos)
|
||||
|
||||
z = property(fget=get_z, fset=set_z)
|
||||
|
||||
def get_attributes(self):
|
||||
"""Retrieves all values of all attributes from this object and displays them in a dictionary whose keys are determined by this object's attribute_mapping"""
|
||||
res = {}
|
||||
for k in self.attribute_mapping:
|
||||
try:
|
||||
res[k] = self.get_attribute(k)
|
||||
except BassError:
|
||||
pass
|
||||
return res
|
57
src/sound_lib/config.py
Normal file
57
src/sound_lib/config.py
Normal file
@ -0,0 +1,57 @@
|
||||
import collections
|
||||
import ctypes
|
||||
from sound_lib.external import pybass
|
||||
from sound_lib.main import bass_call, bass_call_0
|
||||
|
||||
class BassConfig(collections.Mapping):
|
||||
config_map = {
|
||||
'3d_algorithm': pybass.BASS_CONFIG_3DALGORITHM,
|
||||
'buffer': pybass.BASS_CONFIG_BUFFER ,
|
||||
'curve_vol': pybass.BASS_CONFIG_CURVE_VOL,
|
||||
'curve_pan': pybass.BASS_CONFIG_CURVE_PAN,
|
||||
'dev_buffer': pybass.BASS_CONFIG_DEV_BUFFER,
|
||||
'dev_default': pybass.BASS_CONFIG_DEV_DEFAULT,
|
||||
'float_dsp': pybass.BASS_CONFIG_FLOATDSP,
|
||||
'gvol_music': pybass.BASS_CONFIG_GVOL_MUSIC,
|
||||
'gvol_sample': pybass.BASS_CONFIG_GVOL_SAMPLE,
|
||||
'gvol_stream': pybass.BASS_CONFIG_GVOL_STREAM,
|
||||
'music_virtual': pybass.BASS_CONFIG_MUSIC_VIRTUAL,
|
||||
'net_agent': pybass.BASS_CONFIG_NET_AGENT,
|
||||
'net_buffer': pybass.BASS_CONFIG_NET_BUFFER,
|
||||
'net_passive': pybass.BASS_CONFIG_NET_PASSIVE,
|
||||
'net_playlist': pybass.BASS_CONFIG_NET_PLAYLIST,
|
||||
'net_prebuf': pybass.BASS_CONFIG_NET_PREBUF,
|
||||
'net_proxy': pybass.BASS_CONFIG_NET_PROXY,
|
||||
'net_read_timeout': pybass.BASS_CONFIG_NET_READTIMEOUT,
|
||||
'net_timeout': pybass.BASS_CONFIG_NET_TIMEOUT,
|
||||
'pause_no_play': pybass.BASS_CONFIG_PAUSE_NOPLAY,
|
||||
'rec_buffer': pybass.BASS_CONFIG_REC_BUFFER,
|
||||
'src': pybass.BASS_CONFIG_SRC,
|
||||
'src_sample': pybass.BASS_CONFIG_SRC_SAMPLE,
|
||||
'unicode': pybass.BASS_CONFIG_UNICODE,
|
||||
'update_period': pybass.BASS_CONFIG_UPDATEPERIOD,
|
||||
'update_threads': pybass.BASS_CONFIG_UPDATETHREADS,
|
||||
'verify': pybass.BASS_CONFIG_VERIFY,
|
||||
'vista_speakers': pybass.BASS_CONFIG_VISTA_SPEAKERS,
|
||||
}
|
||||
|
||||
ptr_config = (pybass.BASS_CONFIG_NET_AGENT, pybass.BASS_CONFIG_NET_PROXY)
|
||||
|
||||
def __getitem__(self, key):
|
||||
key = self.config_map.get(key, key)
|
||||
if key in self.ptr_config:
|
||||
return ctypes.string_at(bass_call(pybass.BASS_GetConfigPtr, key))
|
||||
return bass_call_0(pybass.BASS_GetConfig, key)
|
||||
|
||||
def __setitem__(self, key, val):
|
||||
key = self.config_map.get(key, key)
|
||||
if key in self.ptr_config:
|
||||
return bass_call(pybass.BASS_SetConfigPtr, key, ctypes.create_string_buffer(val))
|
||||
return bass_call(pybass.BASS_SetConfig, key, val)
|
||||
|
||||
def __iter__(self):
|
||||
for key in self.config_map.keys():
|
||||
yield key
|
||||
|
||||
def __len__(self):
|
||||
return len(self.config_map)
|
1
src/sound_lib/effects/__init__.py
Normal file
1
src/sound_lib/effects/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .tempo import Tempo
|
39
src/sound_lib/effects/bass.py
Normal file
39
src/sound_lib/effects/bass.py
Normal file
@ -0,0 +1,39 @@
|
||||
from __future__ import absolute_import
|
||||
from sound_lib.external import pybass
|
||||
from .effect import SoundEffect
|
||||
|
||||
class Chorus(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_CHORUS
|
||||
struct = pybass.BASS_DX8_CHORUS
|
||||
|
||||
class Echo(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_ECHO
|
||||
struct = pybass.BASS_DX8_ECHO
|
||||
|
||||
class Compressor(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_COMPRESSOR
|
||||
struct = pybass.BASS_DX8_COMPRESSOR
|
||||
|
||||
class Reverb(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_REVERB
|
||||
struct = pybass.BASS_DX8_REVERB
|
||||
|
||||
class Distortion(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_DISTORTION
|
||||
struct = pybass.BASS_DX8_DISTORTION
|
||||
|
||||
class Flanger(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_FLANGER
|
||||
struct = pybass.BASS_DX8_FLANGER
|
||||
|
||||
class Gargle(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_GARGLE
|
||||
struct = pybass.BASS_DX8_GARGLE
|
||||
|
||||
class I3DL2Reverb(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_I3DL2REVERB
|
||||
struct = pybass.BASS_DX8_I3DL2REVERB
|
||||
|
||||
class ParamEq(SoundEffect):
|
||||
effect_type = pybass.BASS_FX_DX8_PARAMEQ
|
||||
struct = pybass.BASS_DX8_PARAMEQ
|
14
src/sound_lib/effects/bass_fx.py
Normal file
14
src/sound_lib/effects/bass_fx.py
Normal file
@ -0,0 +1,14 @@
|
||||
from __future__ import absolute_import
|
||||
from sound_lib.external import pybass_fx
|
||||
from .effect import SoundEffect
|
||||
|
||||
class Volume(SoundEffect):
|
||||
effect_type = pybass_fx.BASS_FX_BFX_VOLUME
|
||||
struct = pybass_fx.BASS_BFX_VOLUME
|
||||
|
||||
class PeakEq(SoundEffect):
|
||||
effect_type = pybass_fx.BASS_FX_BFX_PEAKEQ
|
||||
struct = pybass_fx.BASS_BFX_PEAKEQ
|
||||
class DAmp(SoundEffect):
|
||||
effect_type = pybass_fx.BASS_FX_BFX_DAMP
|
||||
struct = pybass_fx.BASS_BFX_DAMP
|
71
src/sound_lib/effects/effect.py
Normal file
71
src/sound_lib/effects/effect.py
Normal file
@ -0,0 +1,71 @@
|
||||
from future.builtins import object
|
||||
from sound_lib.main import bass_call
|
||||
import ctypes
|
||||
from sound_lib.external import pybass
|
||||
import string #for the alphabet!
|
||||
|
||||
class SoundEffect(object):
|
||||
|
||||
def __init__(self, channel, type=None, priority=0):
|
||||
self.original_channel = channel
|
||||
if hasattr(channel, 'handle'):
|
||||
channel = channel.handle
|
||||
if type is None:
|
||||
type = self.effect_type
|
||||
self.effect_type = type
|
||||
self.priority = priority
|
||||
self.handle = bass_call(pybass.BASS_ChannelSetFX, channel, type, priority)
|
||||
|
||||
def get_parameters(self):
|
||||
"""Retrieves the parameters of an effect."""
|
||||
res = {}
|
||||
params = self.struct()
|
||||
bass_call(pybass.BASS_FXGetParameters, self.handle, ctypes.pointer(params))
|
||||
for f in params._fields_:
|
||||
res[f[0]] = getattr(params, f[0])
|
||||
return res
|
||||
|
||||
def set_parameters(self, parameters):
|
||||
params = self.struct()
|
||||
for p, v in parameters.items():
|
||||
setattr(params, p, v)
|
||||
bass_call(pybass.BASS_FXSetParameters, self.handle, ctypes.pointer(params))
|
||||
|
||||
def __dir__(self):
|
||||
res = dir(self.__class__)
|
||||
return res + self._get_pythonic_effect_fields()
|
||||
|
||||
def _get_effect_fields(self):
|
||||
return [i[0] for i in self.struct._fields_]
|
||||
|
||||
def _get_pythonic_effect_fields(self):
|
||||
return [self._bass_to_python(i) for i in self._get_effect_fields() if not i.startswith('_') ]
|
||||
|
||||
def _bass_to_python(self, func):
|
||||
for c in string.ascii_lowercase:
|
||||
func = func.replace(c.upper(), '_%s' % c)
|
||||
if func.startswith('_'):
|
||||
func = func[1:]
|
||||
return func[2:]
|
||||
|
||||
def _python_to_bass(self, func):
|
||||
for c in string.ascii_lowercase:
|
||||
func = func.replace('_%s' % c, c.upper())
|
||||
func = '%s%s' % (func[0].upper(), func[1:])
|
||||
for f in self._get_effect_fields():
|
||||
if f.endswith(func):
|
||||
func = f
|
||||
return func
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return self.get_parameters()[self._python_to_bass(attr)]
|
||||
|
||||
def __setattr__(self, attr, val):
|
||||
if attr not in self._get_pythonic_effect_fields():
|
||||
return super(SoundEffect, self).__setattr__(attr, val)
|
||||
params = self.get_parameters()
|
||||
key = self._python_to_bass(attr)
|
||||
if key not in params:
|
||||
raise AttributeError('Unable to set attribute, suspect issue with base name-munging code')
|
||||
params[key] = val
|
||||
self.set_parameters(params)
|
65
src/sound_lib/effects/tempo.py
Normal file
65
src/sound_lib/effects/tempo.py
Normal file
@ -0,0 +1,65 @@
|
||||
import ctypes
|
||||
from sound_lib.external import pybass, pybass_fx
|
||||
from sound_lib.stream import BaseStream
|
||||
from sound_lib.channel import Channel
|
||||
from sound_lib.main import bass_call, bass_call_0
|
||||
|
||||
class Tempo(BaseStream):
|
||||
|
||||
def __init__(self, channel, flags=0, loop=False, software=False, three_d=False, sample_fx=False, autofree=False, decode=False, free_source=False):
|
||||
flags = flags | self.flags_for(loop=False, software=False, three_d=False, sample_fx=False, autofree=False, decode=False, free_source=False)
|
||||
self.channel = channel
|
||||
if isinstance(channel, Channel):
|
||||
channel = channel.handle
|
||||
handle = bass_call(pybass_fx.BASS_FX_TempoCreate, channel, flags)
|
||||
super(Tempo, self).__init__(handle)
|
||||
self.add_attributes_to_mapping(
|
||||
tempo=pybass_fx.BASS_ATTRIB_TEMPO,
|
||||
tempo_pitch=pybass_fx.BASS_ATTRIB_TEMPO_PITCH,
|
||||
tempo_freq=pybass_fx.BASS_ATTRIB_TEMPO_FREQ,
|
||||
)
|
||||
|
||||
|
||||
@property
|
||||
def tempo(self):
|
||||
"""The tempo of a channel."""
|
||||
return self.get_attribute(pybass_fx.BASS_ATTRIB_TEMPO)
|
||||
|
||||
@tempo.setter
|
||||
def tempo(self, val):
|
||||
self.set_attribute('tempo', val)
|
||||
|
||||
@property
|
||||
def tempo_pitch(self):
|
||||
return self.get_attribute('tempo_pitch')
|
||||
|
||||
@tempo_pitch.setter
|
||||
def tempo_pitch(self, val):
|
||||
self.set_attribute('tempo_pitch', val)
|
||||
|
||||
@property
|
||||
def tempo_freq(self):
|
||||
return self.get_attribute('tempo_freq')
|
||||
|
||||
@tempo_freq.setter
|
||||
def tempo_freq(self, val):
|
||||
self.set_attribute('tempo_freq', val)
|
||||
|
||||
def setup_flag_mapping(self):
|
||||
super(Tempo, self).setup_flag_mapping()
|
||||
self.flag_mapping.update({
|
||||
'free_source': pybass_fx.BASS_FX_FREESOURCE,
|
||||
})
|
||||
|
||||
def get_source(self):
|
||||
source = pybass_fx.BASS_FX_TempoGetSource(self.handle)
|
||||
if source == self.channel.handle:
|
||||
source = self.channel
|
||||
return source
|
||||
|
||||
source = property(fget=get_source)
|
||||
|
||||
def get_rate_ratio(self):
|
||||
return bass_call(pybass_fx.BASS_FX_TempoGetRateRatio, self.handle)
|
||||
|
||||
rate_ratio = property(fget=get_rate_ratio)
|
81
src/sound_lib/encoder.py
Normal file
81
src/sound_lib/encoder.py
Normal file
@ -0,0 +1,81 @@
|
||||
from __future__ import absolute_import
|
||||
from .external import pybass, pybassenc
|
||||
from .main import bass_call, bass_call_0, FlagObject
|
||||
|
||||
class Encoder(FlagObject):
|
||||
|
||||
def setup_flag_mapping(self):
|
||||
#super(Encoder, self).setup_flag_mapping()
|
||||
self.flag_mapping = {
|
||||
'pcm': pybassenc.BASS_ENCODE_PCM,
|
||||
'no_header': pybassenc.BASS_ENCODE_NOHEAD,
|
||||
'rf64': pybassenc.BASS_ENCODE_RF64,
|
||||
'big_endian': pybassenc.BASS_ENCODE_BIGEND,
|
||||
'fp_8bit': pybassenc.BASS_ENCODE_FP_8BIT,
|
||||
'fp_16bit': pybassenc.BASS_ENCODE_FP_16BIT,
|
||||
'fp_24bit': pybassenc.BASS_ENCODE_FP_24BIT,
|
||||
'fp_32bit': pybassenc.BASS_ENCODE_FP_32BIT,
|
||||
'queue': pybassenc.BASS_ENCODE_QUEUE,
|
||||
'limit': pybassenc.BASS_ENCODE_LIMIT,
|
||||
'no_limit': pybassenc.BASS_ENCODE_CAST_NOLIMIT,
|
||||
'pause': pybassenc.BASS_ENCODE_PAUSE,
|
||||
'autofree': pybassenc.BASS_ENCODE_AUTOFREE,
|
||||
'unicode': pybass.BASS_UNICODE,
|
||||
}
|
||||
|
||||
def __init__(self, source, command_line, pcm=False, no_header=False, rf64=False, big_endian=False, fp_8bit=False, fp_16bit=False, fp_24bit=False, fp_32bit=False, queue=False, limit=False, no_limit=False, pause=True, autofree=False, callback=None, user=None):
|
||||
self.setup_flag_mapping()
|
||||
flags = self.flags_for(pcm=pcm, no_header=no_header, rf64=rf64, big_endian=big_endian, fp_8bit=fp_8bit, fp_16bit=fp_16bit, fp_24bit=fp_24bit, fp_32bit=fp_32bit, queue=queue, limit=limit, no_limit=no_limit, pause=pause, autofree=autofree) #fwiw!
|
||||
self.source = source
|
||||
source_handle = source.handle
|
||||
if callback is None:
|
||||
callback = lambda *a: None
|
||||
callback = pybassenc.ENCODEPROC(callback)
|
||||
self.callback = callback
|
||||
self.handle = bass_call(pybassenc.BASS_Encode_Start, source_handle, command_line, flags, callback, user)
|
||||
|
||||
@property
|
||||
def paused(self):
|
||||
return bass_call_0(pybassenc.BASS_Encode_IsActive, self.handle) == pybass.BASS_ACTIVE_PAUSED
|
||||
|
||||
@paused.setter
|
||||
def paused(self, paused):
|
||||
return bass_call(pybassenc.BASS_Encode_SetPaused, self.handle, paused)
|
||||
|
||||
def is_stopped(self):
|
||||
return bass_call_0(pybassenc.BASS_Encode_IsActive, self.handle) == pybass.BASS_ACTIVE_STOPPED
|
||||
|
||||
|
||||
def stop(self):
|
||||
return bass_call(pybassenc.BASS_Encode_Stop, self.handle)
|
||||
|
||||
class BroadcastEncoder(Encoder):
|
||||
|
||||
def __init__(self, source_encoder, server, password, content, name=None, url=None, genre=None, description=None, headers=None, bitrate=0, public=False):
|
||||
contents = {
|
||||
'mp3': pybassenc.BASS_ENCODE_TYPE_MP3,
|
||||
'ogg': pybassenc.BASS_ENCODE_TYPE_OGG,
|
||||
'aac': pybassenc.BASS_ENCODE_TYPE_AAC
|
||||
}
|
||||
if content in contents:
|
||||
content = contents[content]
|
||||
self.source_encoder = source_encoder
|
||||
handle = source_encoder.handle
|
||||
self.server = server
|
||||
self.password = password
|
||||
self.status = bass_call(pybassenc.BASS_Encode_CastInit, handle, server, password, content, name, url, genre, description, headers, bitrate, public)
|
||||
|
||||
def set_title(self, title=None, url=None):
|
||||
return bass_call(pybassenc.BASS_Encode_CastSetTitle, self.source_encoder.handle, title, url)
|
||||
|
||||
def get_stats(self, type, password=None):
|
||||
types = {
|
||||
'shoutcast': pybassenc.BASS_ENCODE_STATS_SHOUT,
|
||||
'icecast': pybassenc.BASS_ENCODE_STATS_ICE,
|
||||
'icecast_server': pybassenc.BASS_ENCODE_STATS_ICESERV,
|
||||
}
|
||||
if type in types:
|
||||
type = types[type]
|
||||
if password is None:
|
||||
password = self.password
|
||||
return bass_call(pybassenc.BASS_Encode_CastGetStats, self.handle, type, password)
|
9
src/sound_lib/external/__init__.py
vendored
Normal file
9
src/sound_lib/external/__init__.py
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import platform
|
||||
#if platform.system() == 'Windows':
|
||||
# import sound_lib.external.pybasswma
|
||||
if platform.system() != 'Darwin':
|
||||
import sound_lib.external.pybass_aac
|
||||
import sound_lib.external.pybass_alac
|
||||
import sound_lib.external.pybassopus
|
||||
import sound_lib.external.pybassflac
|
||||
import sound_lib.external.pybassmidi
|
9
src/sound_lib/external/paths.py
vendored
Normal file
9
src/sound_lib/external/paths.py
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import os
|
||||
from platform_utils.paths import module_path, is_frozen, embedded_data_path
|
||||
|
||||
if is_frozen():
|
||||
x86_path = os.path.join(embedded_data_path(), 'sound_lib', 'lib', 'x86')
|
||||
x64_path = os.path.join(embedded_data_path(), 'sound_lib', 'lib', 'x64')
|
||||
else:
|
||||
x86_path = os.path.join(module_path(), '..', 'lib', 'x86')
|
||||
x64_path = os.path.join(module_path(), '..', 'lib', 'x64')
|
1120
src/sound_lib/external/pybass.py
vendored
Normal file
1120
src/sound_lib/external/pybass.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
54
src/sound_lib/external/pybass_aac.py
vendored
Normal file
54
src/sound_lib/external/pybass_aac.py
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
from __future__ import absolute_import
|
||||
# Copyright(c) Max Kolosov 2009 maxkolosov@inbox.ru
|
||||
# http://vosolok2008.narod.ru
|
||||
# BSD license
|
||||
|
||||
__version__ = '0.1'
|
||||
__versionTime__ = '2009-11-15'
|
||||
__author__ = 'Max Kolosov <maxkolosov@inbox.ru>'
|
||||
__doc__ = '''
|
||||
pybass_aac.py - is ctypes python module for
|
||||
BASS_AAC - extension to the BASS audio library that enables the playback
|
||||
of Advanced Audio Coding and MPEG-4 streams (http://www.maresweb.de).
|
||||
'''
|
||||
|
||||
import os, sys, ctypes
|
||||
from . import pybass
|
||||
from .paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
bass_aac_module = libloader.load_library('bass_aac', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
#Register the plugin with the Bass plugin system.
|
||||
pybass.BASS_PluginLoad(libloader.find_library_path('bass_aac', x86_path=x86_path, x64_path=x64_path), 0)
|
||||
|
||||
QWORD = pybass.QWORD
|
||||
HSTREAM = pybass.HSTREAM
|
||||
DOWNLOADPROC = pybass.DOWNLOADPROC
|
||||
BASS_FILEPROCS = pybass.BASS_FILEPROCS
|
||||
|
||||
|
||||
# Additional BASS_SetConfig options
|
||||
BASS_CONFIG_MP4_VIDEO = 0x10700 # play the audio from MP4 videos
|
||||
|
||||
# Additional tags available from BASS_StreamGetTags (for MP4 files)
|
||||
BASS_TAG_MP4 = 7 # MP4/iTunes metadata
|
||||
|
||||
BASS_AAC_STEREO = 0x400000 # downmatrix to stereo
|
||||
|
||||
# BASS_CHANNELINFO type
|
||||
BASS_CTYPE_STREAM_AAC = 0x10b00 # AAC
|
||||
BASS_CTYPE_STREAM_MP4 = 0x10b01 # MP4
|
||||
|
||||
|
||||
#HSTREAM BASSAACDEF(BASS_AAC_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
|
||||
BASS_AAC_StreamCreateFile = func_type(HSTREAM, ctypes.c_byte, ctypes.c_void_p, QWORD, QWORD, ctypes.c_ulong)(('BASS_AAC_StreamCreateFile', bass_aac_module))
|
||||
#HSTREAM BASSAACDEF(BASS_AAC_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user);
|
||||
BASS_AAC_StreamCreateURL = func_type(HSTREAM, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_ulong, DOWNLOADPROC, ctypes.c_void_p)(('BASS_AAC_StreamCreateURL', bass_aac_module))
|
||||
#HSTREAM BASSAACDEF(BASS_AAC_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user);
|
||||
BASS_AAC_StreamCreateFileUser = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_FILEPROCS), ctypes.c_void_p)(('BASS_AAC_StreamCreateFileUser', bass_aac_module))
|
||||
#HSTREAM BASSAACDEF(BASS_MP4_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
|
||||
BASS_MP4_StreamCreateFile = func_type(HSTREAM, ctypes.c_byte, ctypes.c_void_p, QWORD, QWORD, ctypes.c_ulong)(('BASS_MP4_StreamCreateFile', bass_aac_module))
|
||||
#HSTREAM BASSAACDEF(BASS_MP4_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user);
|
||||
BASS_MP4_StreamCreateFileUser = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_FILEPROCS), ctypes.c_void_p)(('BASS_MP4_StreamCreateFileUser', bass_aac_module))
|
||||
|
24
src/sound_lib/external/pybass_alac.py
vendored
Normal file
24
src/sound_lib/external/pybass_alac.py
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
from __future__ import absolute_import
|
||||
"BASS_ALAC wrapper by Christopher Toth"""
|
||||
|
||||
import ctypes
|
||||
import os
|
||||
from . import pybass
|
||||
from .paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
bass_fx_module = libloader.load_library('bass_alac', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
|
||||
pybass.BASS_PluginLoad(libloader.find_library_path('bass_alac', x86_path=x86_path, x64_path=x64_path), 0)
|
||||
|
||||
BASS_TAG_MP4 = 7
|
||||
BASS_CTYPE_STREAM_ALAC = 0x10e00
|
||||
|
||||
|
||||
#HSTREAM BASSALACDEF(BASS_ALAC_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
|
||||
BASS_ALAC_StreamCreateFile = func_type(pybass.HSTREAM, ctypes.c_byte, ctypes.c_void_p, pybass.QWORD, pybass.QWORD, ctypes.c_ulong)
|
||||
|
||||
#HSTREAM BASSALACDEF(BASS_ALAC_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user);
|
||||
BASS_ALAC_StreamCreateFileUser = func_type(pybass.HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p)
|
||||
|
384
src/sound_lib/external/pybass_fx.py
vendored
Normal file
384
src/sound_lib/external/pybass_fx.py
vendored
Normal file
@ -0,0 +1,384 @@
|
||||
from __future__ import absolute_import
|
||||
from future.builtins import range
|
||||
"BASS_FX wrapper by Christopher Toth"""
|
||||
|
||||
import ctypes
|
||||
import os
|
||||
from . import pybass
|
||||
from .paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
bass_fx_module = libloader.load_library('bass_fx', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
|
||||
|
||||
#Error codes returned by BASS_ErrorGetCode
|
||||
BASS_ERROR_FX_NODECODE = 4000
|
||||
BASS_ERROR_FX_BPMINUSE = 4001
|
||||
|
||||
#Tempo / Reverse / BPM / Beat flag
|
||||
BASS_FX_FREESOURCE = 0x10000
|
||||
|
||||
#BASS_FX Version
|
||||
BASS_FX_GetVersion = func_type(ctypes.c_ulong)(('BASS_FX_GetVersion', bass_fx_module))
|
||||
|
||||
|
||||
"""D S P (Digital Signal Processing)"""
|
||||
|
||||
"""
|
||||
Multi-channel order of each channel is as follows:
|
||||
3 channels left-front, right-front, center.
|
||||
4 channels left-front, right-front, left-rear/side, right-rear/side.
|
||||
6 channels (5.1) left-front, right-front, center, LFE, left-rear/side, right-rear/side.
|
||||
8 channels (7.1) left-front, right-front, center, LFE, left-rear/side, right-rear/side, left-rear center, right-rear center.
|
||||
"""
|
||||
|
||||
#DSP channels flags
|
||||
BASS_BFX_CHANALL = -1 #all channels at once (as by default)
|
||||
BASS_BFX_CHANNONE = 0 #disable an effect for all channels
|
||||
BASS_BFX_CHAN1 = 1 #left-front channel
|
||||
BASS_BFX_CHAN2 = 2 #right-front channel
|
||||
BASS_BFX_CHAN3 = 4 #see above info
|
||||
BASS_BFX_CHAN4 = 8 #see above info
|
||||
BASS_BFX_CHAN5 = 16
|
||||
BASS_BFX_CHAN6 = 32
|
||||
BASS_BFX_CHAN7 = 64
|
||||
BASS_BFX_CHAN8 = 128
|
||||
|
||||
#DSP effects
|
||||
(
|
||||
BASS_FX_BFX_ROTATE,
|
||||
BASS_FX_BFX_ECHO,
|
||||
BASS_FX_BFX_FLANGER,
|
||||
BASS_FX_BFX_VOLUME,
|
||||
BASS_FX_BFX_PEAKEQ,
|
||||
BASS_FX_BFX_REVERB,
|
||||
BASS_FX_BFX_LPF,
|
||||
BASS_FX_BFX_MIX,
|
||||
BASS_FX_BFX_DAMP,
|
||||
BASS_FX_BFX_AUTOWAH,
|
||||
BASS_FX_BFX_ECHO2,
|
||||
BASS_FX_BFX_PHASER,
|
||||
BASS_FX_BFX_ECHO3,
|
||||
BASS_FX_BFX_CHORUS,
|
||||
BASS_FX_BFX_APF,
|
||||
BASS_FX_BFX_COMPRESSOR,
|
||||
BASS_FX_BFX_DISTORTION,
|
||||
BASS_FX_BFX_COMPRESSOR2,
|
||||
BASS_FX_BFX_VOLUME_ENV,
|
||||
BASS_FX_BFX_BQF,
|
||||
) = range(0x10000, 0x10000+20)
|
||||
|
||||
#BiQuad filters
|
||||
(
|
||||
BASS_BFX_BQF_LOWPASS,
|
||||
BASS_BFX_BQF_HIGHPASS,
|
||||
BASS_BFX_BQF_BANDPASS, #constant 0 dB peak gain
|
||||
BASS_BFX_BQF_BANDPASS_Q, #constant skirt gain, peak gain = Q
|
||||
BASS_BFX_BQF_NOTCH,
|
||||
BASS_BFX_BQF_ALLPASS,
|
||||
BASS_BFX_BQF_PEAKINGEQ,
|
||||
BASS_BFX_BQF_LOWSHELF,
|
||||
BASS_BFX_BQF_HIGHSHELF,
|
||||
) = range(9)
|
||||
|
||||
#Echo
|
||||
class BASS_BFX_ECHO(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fLevel', ctypes.c_float), #[0....1....n] linear
|
||||
('lDelay', ctypes.c_int), #[1200..30000]
|
||||
]
|
||||
|
||||
#Flanger
|
||||
class BASS_BFX_FLANGER(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fWetDry', ctypes.c_float), #[0....1....n] linear
|
||||
('fSpeed', ctypes.c_float), #[0......0.09]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#volume
|
||||
class BASS_BFX_VOLUME(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s or 0 for global volume control
|
||||
('fVolume', ctypes.c_float), #[0....1....n] linear
|
||||
]
|
||||
|
||||
#Peaking Equalizer
|
||||
class BASS_BFX_PEAKEQ(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('lBand', ctypes.c_int), #[0...............n] more bands means more memory & cpu usage
|
||||
('fBandwidth', ctypes.c_float), #[0.1...........<10] in octaves - fQ is not in use (Bandwidth has a priority over fQ)
|
||||
('fQ', ctypes.c_float), #[0...............1] the EE kinda definition (linear) (if Bandwidth is not in use)
|
||||
('fCenter', ctypes.c_float), #[1Hz..<info.freq/2] in Hz
|
||||
('fGain', ctypes.c_float), #[-15dB...0...+15dB] in dB
|
||||
('lChannel', ctypes.c_float), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Reverb
|
||||
class BASS_BFX_REVERB(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fLevel', ctypes.c_float), #[0....1....n] linear
|
||||
('lDelay', ctypes.c_int), #[1200..10000]
|
||||
]
|
||||
|
||||
#Low Pass Filter
|
||||
class BASS_BFX_LPF(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fResonance', ctypes.c_float), #[0.01...........10]
|
||||
('fCutOffFreq', ctypes.c_float), #[1Hz...info.freq/2] cutoff frequency
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Swap, remap and mix
|
||||
class BASS_BFX_MIX(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('lChannel', ctypes.c_int), #an array of channels to mix using BASS_BFX_CHANxxx flag/s (lChannel[0] is left channel...)
|
||||
]
|
||||
|
||||
#Dynamic Amplification
|
||||
class BASS_BFX_DAMP(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fTarget', ctypes.c_float), #target volume level [0<......1] linear
|
||||
('fQuiet', ctypes.c_float), #quiet volume level [0.......1] linear
|
||||
('fRate', ctypes.c_float), #amp adjustment rate [0.......1] linear
|
||||
('fGain', ctypes.c_float), #amplification level [0...1...n] linear
|
||||
('fDelay', ctypes.c_float), #delay in seconds before increasing level [0.......n] linear
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Auto WAH
|
||||
class BASS_BFX_AUTOWAH(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fDryMix', ctypes.c_float), #dry (unaffected) signal mix [-2......2]
|
||||
('fWetMix', ctypes.c_float), #wet (affected) signal mix [-2......2]
|
||||
('fFeedback', ctypes.c_float), #feedback [-1......1]
|
||||
('fRate', ctypes.c_float), #rate of sweep in cycles per second [0<....<10]
|
||||
('fRange', ctypes.c_float), #sweep range in octaves [0<....<10]
|
||||
('fFreq', ctypes.c_float), #base frequency of sweep Hz [0<...1000]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Echo 2
|
||||
class BASS_BFX_ECHO2(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fDryMix', ctypes.c_float), #dry (unaffected) signal mix [-2......2]
|
||||
('fWetMix', ctypes.c_float), #wet (affected) signal mix [-2......2]
|
||||
('fFeedback', ctypes.c_float), #feedback [-1......1]
|
||||
('fDelay', ctypes.c_float), #delay sec [0<......n]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Phaser
|
||||
class BASS_BFX_PHASER(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fDryMix', ctypes.c_float), #dry (unaffected) signal mix [-2......2]
|
||||
('fWetMix', ctypes.c_float), #wet (affected) signal mix [-2......2]
|
||||
('fFeedback', ctypes.c_float), #feedback [-1......1]
|
||||
('fRate', ctypes.c_float), #rate of sweep in cycles per second [0<....<10]
|
||||
('fRange', ctypes.c_float), #sweep range in octaves [0<....<10]
|
||||
('fFreq', ctypes.c_float), #base frequency of sweep [0<...1000]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Echo 3
|
||||
class BASS_BFX_ECHO3(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fDryMix', ctypes.c_float), #dry (unaffected) signal mix [-2......2]
|
||||
('fWetMix', ctypes.c_float), #wet (affected) signal mix [-2......2]
|
||||
('fDelay', ctypes.c_float), #delay sec [0<......n]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Chorus
|
||||
class BASS_BFX_CHORUS(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fDryMix', ctypes.c_float), #dry (unaffected) signal mix [-2......2]
|
||||
('fWetMix', ctypes.c_float), #wet (affected) signal mix [-2......2]
|
||||
('fFeedback', ctypes.c_float), #feedback [-1......1]
|
||||
('fMinSweep', ctypes.c_float), #minimal delay ms [0<...6000]
|
||||
('fMaxSweep', ctypes.c_float), #maximum delay ms [0<...6000]
|
||||
('fRate', ctypes.c_float), #rate ms/s [0<...1000]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#All Pass Filter
|
||||
class BASS_BFX_APF(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fGain', ctypes.c_float), #reverberation time [-1=<..<=1]
|
||||
('fDelay', ctypes.c_float), #delay sec [0<....<=n]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Compressor
|
||||
class BASS_BFX_COMPRESSOR(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fThreshold', ctypes.c_float), #compressor threshold [0<=...<=1]
|
||||
('fAttacktime', ctypes.c_float), #attack time ms [0<.<=1000]
|
||||
('fReleasetime', ctypes.c_float), #release time ms [0<.<=5000]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Distortion
|
||||
class BASS_BFX_DISTORTION(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fDrive', ctypes.c_float), #distortion drive [0<=...<=5]
|
||||
('fDryMix', ctypes.c_float), #dry (unaffected) signal mix [-5<=..<=5]
|
||||
('fWetMix', ctypes.c_float), #wet (affected) signal mix [-5<=..<=5]
|
||||
('fFeedback', ctypes.c_float), #feedback [-1<=..<=1]
|
||||
('fVolume', ctypes.c_float), #distortion volume [0=<...<=2]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
#Compressor 2
|
||||
class BASS_BFX_COMPRESSOR2(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('fGain', ctypes.c_float), #output gain of signal after compression [-60....60] in dB
|
||||
('fThreshold', ctypes.c_float), #point at which compression begins [-60.....0] in dB
|
||||
('fRatio', ctypes.c_float), #compression ratio [1.......n]
|
||||
('fAttack', ctypes.c_float), #attack time in ms [0.01.1000]
|
||||
('fRelease', ctypes.c_float), #release time in ms [0.01.5000]
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
class BASS_BFX_ENV_NODE(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('pos', ctypes.c_long), #node position in seconds (1st envelope node must be at position 0)
|
||||
('val', ctypes.c_float), #node value
|
||||
]
|
||||
|
||||
#Volume envelope
|
||||
class BASS_BFX_VOLUME_ENV(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
('lNodeCount', ctypes.c_int), #number of nodes
|
||||
('pNodes', BASS_BFX_ENV_NODE), #the nodes
|
||||
('bFollow', ctypes.c_bool), #follow source position
|
||||
]
|
||||
|
||||
#BiQuad Filters
|
||||
|
||||
class BASS_BFX_BQF(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('lFilter', ctypes.c_int), #BASS_BFX_BQF_xxx filter types
|
||||
('fCenter', ctypes.c_float), #[1Hz..<info.freq/2] Cutoff (central) frequency in Hz
|
||||
('fGain', ctypes.c_float), #[-15dB...0...+15dB] Used only for PEAKINGEQ and Shelving filters in dB
|
||||
('fBandwidth', ctypes.c_float), #[0.1...........<10] Bandwidth in octaves (fQ is not in use (fBandwidth has a priority over fQ))
|
||||
#(between -3 dB frequencies for BANDPASS and NOTCH or between midpoint
|
||||
#(fGgain/2) gain frequencies for PEAKINGEQ)
|
||||
('fQ', ctypes.c_float), #[0.1.............1] The EE kinda definition (linear) (if fBandwidth is not in use)
|
||||
('fS', ctypes.c_float), #[0.1.............1] A "shelf slope" parameter (linear) (used only with Shelving filters)
|
||||
#when fS = 1, the shelf slope is as steep as you can get it and remain monotonically
|
||||
#increasing or decreasing gain with frequency.
|
||||
('lChannel', ctypes.c_int), #BASS_BFX_CHANxxx flag/s
|
||||
]
|
||||
|
||||
"""TEMPO / PITCH SCALING / SAMPLERATE"""
|
||||
|
||||
"""NOTES: 1. Supported only - mono / stereo - channels
|
||||
2. Enable Tempo supported flags in BASS_FX_TempoCreate and the others to source handle.
|
||||
tempo attributes (BASS_ChannelSet/GetAttribute)"""
|
||||
|
||||
(
|
||||
BASS_ATTRIB_TEMPO,
|
||||
BASS_ATTRIB_TEMPO_PITCH,
|
||||
BASS_ATTRIB_TEMPO_FREQ,
|
||||
) = range(0x10000, 0x10000+3)
|
||||
|
||||
#tempo attributes options
|
||||
#[option] [value]
|
||||
|
||||
(
|
||||
BASS_ATTRIB_TEMPO_OPTION_USE_AA_FILTER, #TRUE (default) / FALSE
|
||||
BASS_ATTRIB_TEMPO_OPTION_AA_FILTER_LENGTH, #32 default (8 .. 128 taps)
|
||||
BASS_ATTRIB_TEMPO_OPTION_USE_QUICKALGO, #TRUE / FALSE (default)
|
||||
BASS_ATTRIB_TEMPO_OPTION_SEQUENCE_MS, #82 default, 0 = automatic
|
||||
BASS_ATTRIB_TEMPO_OPTION_SEEKWINDOW_MS, #28 default, 0 = automatic
|
||||
BASS_ATTRIB_TEMPO_OPTION_OVERLAP_MS, #8 default
|
||||
BASS_ATTRIB_TEMPO_OPTION_PREVENT_CLICK, #TRUE / FALSE (default)
|
||||
) = range(0x10000, 0x10000+7)
|
||||
|
||||
#HSTREAM BASS_FXDEF(BASS_FX_TempoCreate)(DWORD chan, DWORD flags);
|
||||
BASS_FX_TempoCreate = func_type(pybass.HSTREAM, ctypes.c_ulong, ctypes.c_ulong)(('BASS_FX_TempoCreate', bass_fx_module))
|
||||
|
||||
#DWORD BASS_FXDEF(BASS_FX_TempoGetSource)(HSTREAM chan);
|
||||
BASS_FX_TempoGetSource = func_type(ctypes.c_ulong, pybass.HSTREAM)(('BASS_FX_TempoGetSource', bass_fx_module))
|
||||
|
||||
#float BASS_FXDEF(BASS_FX_TempoGetRateRatio)(HSTREAM chan);
|
||||
BASS_FX_TempoGetRateRatio = func_type(ctypes.c_float, pybass.HSTREAM)(('BASS_FX_TempoGetRateRatio', bass_fx_module))
|
||||
|
||||
"""R E V E R S E"""
|
||||
"""NOTES: 1. MODs won't load without BASS_MUSIC_PRESCAN flag.
|
||||
2. Enable Reverse supported flags in BASS_FX_ReverseCreate and the others to source handle."""
|
||||
|
||||
#reverse attribute (BASS_ChannelSet/GetAttribute)
|
||||
BASS_ATTRIB_REVERSE_DIR = 0x11000
|
||||
|
||||
#playback directions
|
||||
BASS_FX_RVS_REVERSE = -1
|
||||
BASS_FX_RVS_FORWARD = 1
|
||||
|
||||
#HSTREAM BASS_FXDEF(BASS_FX_ReverseCreate)(DWORD chan, float dec_block, DWORD flags);
|
||||
BASS_FX_ReverseCreate = func_type(pybass.HSTREAM, ctypes.c_ulong, ctypes.c_float, ctypes.c_ulong)(('BASS_FX_ReverseCreate', bass_fx_module))
|
||||
|
||||
#DWORD BASS_FXDEF(BASS_FX_ReverseGetSource)(HSTREAM chan);
|
||||
BASS_FX_ReverseGetSource = func_type(ctypes.c_ulong, pybass.HSTREAM)(('BASS_FX_ReverseGetSource', bass_fx_module))
|
||||
|
||||
"""B P M (Beats Per Minute)"""
|
||||
|
||||
#bpm flags
|
||||
BASS_FX_BPM_BKGRND = 1 #if in use, then you can do other processing while detection's in progress. Not available in MacOSX yet. (BPM/Beat)
|
||||
BASS_FX_BPM_MULT2 = 2 #if in use, then will auto multiply bpm by 2 (if BPM < minBPM*2)
|
||||
|
||||
#translation options
|
||||
(
|
||||
BASS_FX_BPM_TRAN_X2, #multiply the original BPM value by 2 (may be called only once & will change the original BPM as well!)
|
||||
BASS_FX_BPM_TRAN_2FREQ, #BPM value to Frequency
|
||||
BASS_FX_BPM_TRAN_FREQ2, #Frequency to BPM value
|
||||
BASS_FX_BPM_TRAN_2PERCENT, #BPM value to Percents
|
||||
BASS_FX_BPM_TRAN_PERCENT2 , #Percents to BPM value
|
||||
) = range(5)
|
||||
|
||||
#typedef void (CALLBACK BPMPROCESSPROC)(DWORD chan, float percent);
|
||||
BPMPROCESSPROC = func_type(None, ctypes.c_float)
|
||||
|
||||
#typedef void (CALLBACK BPMPROC)(DWORD chan, float bpm, void *user);
|
||||
BPMPROC = func_type(None, ctypes.c_long, ctypes.c_float, ctypes.c_void_p)
|
||||
|
||||
#float BASS_FXDEF(BASS_FX_BPM_DecodeGet)(DWORD chan, double startSec, double endSec, DWORD minMaxBPM, DWORD flags, BPMPROCESSPROC *proc);
|
||||
BASS_FX_BPM_DecodeGet = func_type(ctypes.c_float, ctypes.c_ulong, ctypes.c_double, ctypes.c_double, ctypes.c_ulong, ctypes.c_ulong, BPMPROCESSPROC)(('BASS_FX_BPM_DecodeGet', bass_fx_module))
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_CallbackSet)(DWORD handle, BPMPROC *proc, double period, DWORD minMaxBPM, DWORD flags, void *user);
|
||||
BASS_FX_BPM_CallbackSet = func_type(ctypes.c_bool, ctypes.c_ulong, BPMPROC, ctypes.c_double, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_void_p)(('BASS_FX_BPM_CallbackSet', bass_fx_module))
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_CallbackReset)(DWORD handle);
|
||||
BASS_FX_BPM_CallbackReset = func_type(ctypes.c_bool, ctypes.c_ulong)(('BASS_FX_BPM_CallbackReset', bass_fx_module))
|
||||
|
||||
#float BASS_FXDEF(BASS_FX_BPM_Translate)(DWORD handle, float val2tran, DWORD trans);
|
||||
BASS_FX_BPM_Translate = func_type(ctypes.c_float, ctypes.c_ulong, ctypes.c_float, ctypes.c_ulong)(('BASS_FX_BPM_Translate', bass_fx_module))
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_Free)(DWORD handle);
|
||||
BASS_FX_BPM_Free = func_type(ctypes.c_bool, ctypes.c_ulong)(('BASS_FX_BPM_Free', bass_fx_module))
|
||||
|
||||
""" Beat """
|
||||
|
||||
#typedef void (CALLBACK BPMBEATPROC)(DWORD chan, double beatpos, void *user);
|
||||
BPMBEATPROC = func_type(None, ctypes.c_ulong, ctypes.c_double, ctypes.c_void_p)
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_BeatCallbackSet)(DWORD handle, BPMBEATPROC *proc, void *user);
|
||||
BASS_FX_BPM_BeatCallbackSet = func_type(ctypes.c_bool, ctypes.c_ulong, ctypes.c_void_p)(('BASS_FX_BPM_BeatCallbackSet', bass_fx_module))
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_BeatCallbackReset)(DWORD handle);
|
||||
BASS_FX_BPM_BeatCallbackReset = func_type(ctypes.c_bool, ctypes.c_ulong)(('BASS_FX_BPM_BeatCallbackReset', bass_fx_module))
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_BeatDecodeGet)(DWORD chan, double startSec, double endSec, DWORD flags, BPMBEATPROC *proc, void *user);
|
||||
BASS_FX_BPM_BeatDecodeGet = func_type(ctypes.c_bool, ctypes.c_ulong, ctypes.c_double, ctypes.c_double, ctypes.c_ulong, BPMBEATPROC, ctypes.c_void_p)(('BASS_FX_BPM_BeatDecodeGet', bass_fx_module))
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_BeatSetParameters)(DWORD handle, float bandwidth, float centerfreq, float beat_rtime);
|
||||
BASS_FX_BPM_BeatSetParameters = func_type(ctypes.c_bool, ctypes.c_ulong, ctypes.c_float, ctypes.c_float, ctypes.c_float)(('BASS_FX_BPM_BeatSetParameters', bass_fx_module))
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_BeatGetParameters)(DWORD handle, float *bandwidth, float *centerfreq, float *beat_rtime);
|
||||
BASS_FX_BPM_BeatGetParameters = func_type(ctypes.c_bool, ctypes.c_ulong, ctypes.c_float, ctypes.c_float, ctypes.c_float)(('BASS_FX_BPM_BeatGetParameters', bass_fx_module))
|
||||
|
||||
#BOOL BASS_FXDEF(BASS_FX_BPM_BeatFree)(DWORD handle);
|
||||
BASS_FX_BPM_BeatFree = func_type(ctypes.c_bool, ctypes.c_ulong)(('BASS_FX_BPM_BeatFree', bass_fx_module))
|
170
src/sound_lib/external/pybassenc.py
vendored
Normal file
170
src/sound_lib/external/pybassenc.py
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
from __future__ import absolute_import
|
||||
from future.builtins import range
|
||||
"BASSENC wrapper by Christopher Toth"""
|
||||
|
||||
import ctypes
|
||||
import os
|
||||
import platform
|
||||
from . import pybass
|
||||
from .paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
bassenc_module = libloader.load_library('bassenc', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
|
||||
HENCODE = ctypes.c_ulong #encoder handle
|
||||
|
||||
#Additional error codes returned by BASS_ErrorGetCode
|
||||
BASS_ERROR_ACM_CANCEL = 2000 #ACM codec selection cancelled
|
||||
pybass.error_descriptions[BASS_ERROR_ACM_CANCEL] = "ACM codec selection cancelled"
|
||||
BASS_ERROR_CAST_DENIED = 2100 #access denied (invalid password)
|
||||
pybass.error_descriptions[BASS_ERROR_CAST_DENIED] = "access denied (invalid password)"
|
||||
|
||||
#Additional BASS_SetConfig options
|
||||
BASS_CONFIG_ENCODE_PRIORITY = 0x10300
|
||||
BASS_CONFIG_ENCODE_QUEUE = 0x10301
|
||||
BASS_CONFIG_ENCODE_CAST_TIMEOUT = 0x10310
|
||||
|
||||
#Additional BASS_SetConfigPtr options
|
||||
BASS_CONFIG_ENCODE_CAST_PROXY = 0x10311
|
||||
|
||||
#BASS_Encode_Start flags
|
||||
BASS_ENCODE_NOHEAD = 1 #don't send a WAV header to the encoder
|
||||
BASS_ENCODE_FP_8BIT = 2 #convert floating-point sample data to 8-bit integer
|
||||
BASS_ENCODE_FP_16BIT = 4 #convert floating-point sample data to 16-bit integer
|
||||
BASS_ENCODE_FP_24BIT = 6#convert floating-point sample data to 24-bit integer
|
||||
BASS_ENCODE_FP_32BIT = 8 #convert floating-point sample data to 32-bit integer
|
||||
BASS_ENCODE_BIGEND = 16 #big-endian sample data
|
||||
BASS_ENCODE_PAUSE = 32 #start encoding paused
|
||||
BASS_ENCODE_PCM = 64 #write PCM sample data (no encoder)
|
||||
BASS_ENCODE_RF64 = 128 #send an RF64 header
|
||||
BASS_ENCODE_MONO = 256 #convert to mono (if not already)
|
||||
BASS_ENCODE_QUEUE = 512 #queue data to feed encoder asynchronously
|
||||
BASS_ENCODE_CAST_NOLIMIT = 0x1000 #don't limit casting data rate
|
||||
BASS_ENCODE_LIMIT = 0x2000 #limit data rate to real-time
|
||||
BASS_ENCODE_AUTOFREE = 0x40000 #free the encoder when the channel is freed
|
||||
|
||||
#BASS_Encode_GetACMFormat flags
|
||||
BASS_ACM_DEFAULT = 1 #use the format as default selection
|
||||
BASS_ACM_RATE = 2 #only list formats with same sample rate as the source channel
|
||||
BASS_ACM_CHANS = 4 #only list formats with same number of channels (eg. mono/stereo)
|
||||
BASS_ACM_SUGGEST = 8 #suggest a format (HIWORD=format tag)
|
||||
|
||||
#BASS_Encode_GetCount counts
|
||||
|
||||
(
|
||||
BASS_ENCODE_COUNT_IN, #sent to encoder
|
||||
BASS_ENCODE_COUNT_OUT, #received from encoder
|
||||
BASS_ENCODE_COUNT_CAST, #sent to cast server
|
||||
BASS_ENCODE_COUNT_QUEUE, #queued
|
||||
BASS_ENCODE_COUNT_QUEUE_LIMIT, #queue limit
|
||||
BASS_ENCODE_COUNT_QUEUE_FAIL, #failed to queue
|
||||
) = range(6)
|
||||
|
||||
#BASS_Encode_CastInit content MIME types
|
||||
|
||||
BASS_ENCODE_TYPE_MP3 = "audio/mpeg"
|
||||
BASS_ENCODE_TYPE_OGG = "application/ogg"
|
||||
BASS_ENCODE_TYPE_AAC = "audio/aacp"
|
||||
|
||||
#BASS_Encode_CastGetStats types
|
||||
|
||||
BASS_ENCODE_STATS_SHOUT = 0 #Shoutcast stats
|
||||
BASS_ENCODE_STATS_ICE = 1 #Icecast mount-point stats
|
||||
BASS_ENCODE_STATS_ICESERV = 2 #Icecast server stats
|
||||
|
||||
#typedef void (CALLBACK ENCODEPROC)(HENCODE handle, DWORD channel, const void *buffer, DWORD length, void *user);
|
||||
ENCODEPROC = func_type(None, HENCODE, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_void_p)
|
||||
|
||||
#typedef void (CALLBACK ENCODEPROCEX)(HENCODE handle, DWORD channel, const void *buffer, DWORD length, QWORD offset, void *user);
|
||||
ENCODEPROCEX = func_type(None, HENCODE, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, pybass.QWORD, ctypes.c_void_p)
|
||||
|
||||
#typedef BOOL (CALLBACK ENCODECLIENTPROC)(HENCODE handle, BOOL connect, const char *client, char *headers, void *user);
|
||||
ENCODECLIENTPROC = func_type(ctypes.c_byte, HENCODE, ctypes.c_byte, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p)
|
||||
|
||||
#typedef void (CALLBACK ENCODENOTIFYPROC)(HENCODE handle, DWORD status, void *user);
|
||||
ENCODENOTIFYPROC = func_type(None, HENCODE, ctypes.c_ulong, ctypes.c_void_p)
|
||||
|
||||
#Encoder notifications
|
||||
BASS_ENCODE_NOTIFY_ENCODER = 1 #encoder died
|
||||
BASS_ENCODE_NOTIFY_CAST = 2 #cast server connection died
|
||||
BASS_ENCODE_NOTIFY_CAST_TIMEOUT = 0x10000 #cast timeout
|
||||
BASS_ENCODE_NOTIFY_QUEUE_FULL = 0x10001 #queue is out of space
|
||||
|
||||
#BASS_Encode_ServerInit flags
|
||||
BASS_ENCODE_SERVER_NOHTTP = 1 #no HTTP headers
|
||||
|
||||
#DWORD BASSENCDEF(BASS_Encode_GetVersion)();
|
||||
BASS_Encode_GetVersion = func_type(ctypes.c_ulong)(('BASS_Encode_GetVersion', bassenc_module))
|
||||
|
||||
#HENCODE BASSENCDEF(BASS_Encode_Start)(DWORD handle, const char *cmdline, DWORD flags, ENCODEPROC *proc, void *user);
|
||||
BASS_Encode_Start = func_type(HENCODE, ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ENCODEPROC, ctypes.c_void_p)(('BASS_Encode_Start', bassenc_module))
|
||||
|
||||
#HENCODE BASSENCDEF(BASS_Encode_StartLimit)(DWORD handle, const char *cmdline, DWORD flags, ENCODEPROC *proc, void *user, DWORD limit);
|
||||
BASS_Encode_StartLimit = func_type(HENCODE, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ENCODEPROC, ctypes.c_void_p, ctypes.c_ulong)(('BASS_Encode_StartLimit', bassenc_module))
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_AddChunk)(HENCODE handle, const char *id, const void *buffer, DWORD length);
|
||||
BASS_Encode_AddChunk = func_type(ctypes.c_byte, HENCODE, ctypes.c_char_p, ctypes.c_void_p, ctypes.c_ulong)(('BASS_Encode_AddChunk', bassenc_module))
|
||||
|
||||
#DWORD BASSENCDEF(BASS_Encode_IsActive)(DWORD handle);
|
||||
BASS_Encode_IsActive = func_type(ctypes.c_ulong, ctypes.c_ulong)(('BASS_Encode_IsActive', bassenc_module))
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_Stop)(DWORD handle);
|
||||
BASS_Encode_Stop = func_type(ctypes.c_byte, ctypes.c_ulong)(('BASS_Encode_Stop', bassenc_module))
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_StopEx)(DWORD handle, BOOL queue);
|
||||
BASS_Encode_StopEx = func_type(ctypes.c_byte, ctypes.c_ulong, ctypes.c_byte)
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_SetPaused)(DWORD handle, BOOL paused);
|
||||
BASS_Encode_SetPaused = func_type(ctypes.c_byte, ctypes.c_ulong, ctypes.c_byte)(('BASS_Encode_SetPaused', bassenc_module))
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_Write)(DWORD handle, const void *buffer, DWORD length);
|
||||
BASS_Encode_Write = func_type(ctypes.c_byte, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong)(('BASS_Encode_Write', bassenc_module))
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_SetNotify)(DWORD handle, ENCODENOTIFYPROC *proc, void *user);
|
||||
BASS_Encode_SetNotify = func_type(ctypes.c_byte, ctypes.c_ulong, ENCODENOTIFYPROC, ctypes.c_void_p)(('BASS_Encode_SetNotify', bassenc_module))
|
||||
|
||||
#QWORD BASSENCDEF(BASS_Encode_GetCount)(DWORD handle, DWORD count);
|
||||
BASS_Encode_GetCount = func_type(pybass.QWORD, ctypes.c_ulong, ctypes.c_ulong)(('BASS_Encode_GetCount', bassenc_module))
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_SetChannel)(DWORD handle, DWORD channel);
|
||||
BASS_Encode_SetChannel = func_type(ctypes.c_byte, ctypes.c_ulong, ctypes.c_ulong)
|
||||
|
||||
#DWORD BASSENCDEF(BASS_Encode_GetChannel)(HENCODE handle);
|
||||
BASS_Encode_GetChannel = func_type(ctypes.c_ulong, HENCODE)(('BASS_Encode_GetChannel', bassenc_module))
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
#DWORD BASSENCDEF(BASS_Encode_GetACMFormat)(DWORD handle, void *form, DWORD formlen, const char *title, DWORD flags);
|
||||
BASS_Encode_GetACMFormat = func_type(ctypes.c_ulong, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong)(('BASS_Encode_GetACMFormat', bassenc_module))
|
||||
|
||||
#HENCODE BASSENCDEF(BASS_Encode_StartACM)(DWORD handle, const void *form, DWORD flags, ENCODEPROC *proc, void *user);
|
||||
BASS_Encode_StartACM = func_type(HENCODE, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ENCODEPROC, ctypes.c_void_p)(('BASS_Encode_StartACM', bassenc_module))
|
||||
|
||||
#HENCODE BASSENCDEF(BASS_Encode_StartACMFile)(DWORD handle, const void *form, DWORD flags, const char *file);
|
||||
BASS_Encode_StartACMFile = func_type(HENCODE, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_char_p)(('BASS_Encode_StartACMFile', bassenc_module))
|
||||
|
||||
|
||||
if platform.system() == 'Darwin':
|
||||
#HENCODE BASSENCDEF(BASS_Encode_StartCA)(DWORD handle, DWORD ftype, DWORD atype, DWORD flags, DWORD bitrate, ENCODEPROCEX *proc, void *user);
|
||||
BASS_Encode_StartCA = func_type(HENCODE, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ENCODEPROCEX, ctypes.c_void_p)(('ENCODEPROCEX ', bassenc_module))
|
||||
#HENCODE BASSENCDEF(BASS_Encode_StartCAFile)(DWORD handle, DWORD ftype, DWORD atype, DWORD flags, DWORD bitrate, const char *file);
|
||||
BASS_Encode_StartCAFile = func_type(HENCODE, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_char_p)(('BASS_Encode_StartCAFile', bassenc_module))
|
||||
#Broadcasting
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_CastInit)(HENCODE handle, const char *server, const char *pass, const char *content, const char *name, const char *url, const char *genre, const char *desc, const char *headers, DWORD bitrate, BOOL pub);
|
||||
BASS_Encode_CastInit = func_type(ctypes.c_byte, HENCODE, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_byte)(('BASS_Encode_CastInit', bassenc_module))
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_CastSetTitle)(HENCODE handle, const char *title, const char *url);
|
||||
BASS_Encode_CastSetTitle = func_type(ctypes.c_byte, HENCODE, ctypes.c_char_p, ctypes.c_char_p)(('BASS_Encode_CastSetTitle', bassenc_module))
|
||||
|
||||
#const char *BASSENCDEF(BASS_Encode_CastGetStats)(HENCODE handle, DWORD type, const char *pass);
|
||||
BASS_Encode_CastGetStats = func_type(ctypes.c_char_p, HENCODE, ctypes.c_ulong, ctypes.c_char_p)(('BASS_Encode_CastGetStats', bassenc_module))
|
||||
|
||||
#Local audio server
|
||||
|
||||
#DWORD BASSENCDEF(BASS_Encode_ServerInit)(HENCODE handle, const char *port, DWORD buffer, DWORD burst, DWORD flags, ENCODECLIENTPROC *proc, void *user);
|
||||
BASS_Encode_ServerInit = func_type(ctypes.c_ulong, HENCODE, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ENCODECLIENTPROC, ctypes.c_void_p)(('BASS_Encode_ServerInit', bassenc_module))
|
||||
|
||||
#BOOL BASSENCDEF(BASS_Encode_ServerKick)(HENCODE handle, const char *client);
|
||||
BASS_Encode_ServerKick = func_type(ctypes.c_byte, HENCODE, ctypes.c_char_p)(('BASS_Encode_ServerKick', bassenc_module))
|
||||
|
41
src/sound_lib/external/pybassflac.py
vendored
Normal file
41
src/sound_lib/external/pybassflac.py
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
from __future__ import absolute_import
|
||||
# Copyright(c) Max Kolosov 2009 maxkolosov@inbox.ru
|
||||
# http://vosolok2008.narod.ru
|
||||
# BSD license
|
||||
|
||||
__version__ = '0.1'
|
||||
__versionTime__ = '2009-11-15'
|
||||
__author__ = 'Max Kolosov <maxkolosov@inbox.ru>'
|
||||
__doc__ = '''
|
||||
pybassflac.py - is ctypes python module for
|
||||
BASSFLAC - extension to the BASS audio library,
|
||||
enabling the playing of FLAC (Free Lossless Audio Codec) encoded files.
|
||||
'''
|
||||
|
||||
import os, sys, ctypes
|
||||
from . import pybass
|
||||
from .paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
bassflac_module = libloader.load_library('bassflac', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
#Register the plugin with the Bass plugin system.
|
||||
pybass.BASS_PluginLoad(libloader.find_library_path('bassflac', x86_path=x86_path, x64_path=x64_path), 0)
|
||||
|
||||
QWORD = pybass.QWORD
|
||||
HSTREAM = pybass.HSTREAM
|
||||
DOWNLOADPROC = pybass.DOWNLOADPROC
|
||||
BASS_FILEPROCS = pybass.BASS_FILEPROCS
|
||||
|
||||
# BASS_CHANNELINFO type
|
||||
BASS_CTYPE_STREAM_FLAC = 0x10900
|
||||
BASS_CTYPE_STREAM_FLAC_OGG = 0x10901
|
||||
|
||||
|
||||
#HSTREAM BASSFLACDEF(BASS_FLAC_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
|
||||
BASS_FLAC_StreamCreateFile = func_type(HSTREAM, ctypes.c_byte, ctypes.c_void_p, QWORD, QWORD, ctypes.c_ulong)(('BASS_FLAC_StreamCreateFile', bassflac_module))
|
||||
#HSTREAM BASSFLACDEF(BASS_FLAC_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user);
|
||||
BASS_FLAC_StreamCreateURL = func_type(HSTREAM, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_ulong, DOWNLOADPROC, ctypes.c_void_p)(('BASS_FLAC_StreamCreateURL', bassflac_module))
|
||||
#HSTREAM BASSFLACDEF(BASS_FLAC_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user);
|
||||
BASS_FLAC_StreamCreateFileUser = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_FILEPROCS), ctypes.c_void_p)(('BASS_FLAC_StreamCreateFileUser', bassflac_module))
|
||||
|
204
src/sound_lib/external/pybassmidi.py
vendored
Normal file
204
src/sound_lib/external/pybassmidi.py
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
from __future__ import absolute_import
|
||||
# Copyright(c) Max Kolosov 2009 maxkolosov@inbox.ru
|
||||
# http://vosolok2008.narod.ru
|
||||
# BSD license
|
||||
|
||||
__version__ = '0.1'
|
||||
__versionTime__ = '2009-11-15'
|
||||
__author__ = 'Max Kolosov <maxkolosov@inbox.ru>'
|
||||
__doc__ = '''
|
||||
pybassmidi.py - is ctypes python module for
|
||||
BASSMIDI - extension to the BASS audio library,
|
||||
enabling the playing of MIDI files and real-time events,
|
||||
using SF2 soundfonts to provide the sounds.
|
||||
'''
|
||||
|
||||
import sys, ctypes, platform, os
|
||||
from . import pybass
|
||||
from .paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
bassmidi_module = libloader.load_library('bassmidi', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
#Register the plugin with the Bass plugin system.
|
||||
pybass.BASS_PluginLoad(libloader.find_library_path('bassmidi', x86_path=x86_path, x64_path=x64_path), 0)
|
||||
|
||||
HSOUNDFONT = ctypes.c_ulong
|
||||
|
||||
QWORD = pybass.QWORD
|
||||
HSTREAM = pybass.HSTREAM
|
||||
DOWNLOADPROC = pybass.DOWNLOADPROC
|
||||
BASS_FILEPROCS = pybass.BASS_FILEPROCS
|
||||
|
||||
|
||||
# Additional BASS_SetConfig options
|
||||
BASS_CONFIG_MIDI_COMPACT = 0x10400
|
||||
BASS_CONFIG_MIDI_VOICES = 0x10401
|
||||
BASS_CONFIG_MIDI_AUTOFONT = 0x10402
|
||||
|
||||
# Additional BASS_SetConfigPtr options
|
||||
BASS_CONFIG_MIDI_DEFFONT = 0x10403
|
||||
|
||||
# Additional sync types
|
||||
BASS_SYNC_MIDI_MARKER = 0x10000
|
||||
BASS_SYNC_MIDI_CUE = 0x10001
|
||||
BASS_SYNC_MIDI_LYRIC = 0x10002
|
||||
BASS_SYNC_MIDI_TEXT = 0x10003
|
||||
BASS_SYNC_MIDI_EVENT = 0x10004
|
||||
BASS_SYNC_MIDI_TICK = 0x10005
|
||||
BASS_SYNC_MIDI_TIMESIG = 0x10006
|
||||
|
||||
# Additional BASS_MIDI_StreamCreateFile/etc flags
|
||||
BASS_MIDI_DECAYEND = 0x1000
|
||||
BASS_MIDI_NOFX = 0x2000
|
||||
BASS_MIDI_DECAYSEEK = 0x4000
|
||||
|
||||
class BASS_MIDI_FONT(ctypes.Structure):
|
||||
_fields_ = [('font', HSOUNDFONT),#HSOUNDFONT font; // soundfont
|
||||
('preset', ctypes.c_int),#int preset; // preset number (-1=all)
|
||||
('bank', ctypes.c_int)#int bank;
|
||||
]
|
||||
|
||||
class BASS_MIDI_FONTINFO(ctypes.Structure):
|
||||
_fields_ = [('name', ctypes.c_char_p),#const char *name;
|
||||
('copyright', ctypes.c_char_p),#const char *copyright;
|
||||
('comment', ctypes.c_char_p),#const char *comment;
|
||||
('presets', ctypes.c_ulong),#DWORD presets; // number of presets/instruments
|
||||
('samsize', ctypes.c_ulong),#DWORD samsize; // total size (in bytes) of the sample data
|
||||
('samload', ctypes.c_ulong),#DWORD samload; // amount of sample data currently loaded
|
||||
('samtype', ctypes.c_ulong)#DWORD samtype; // sample format (CTYPE) if packed
|
||||
]
|
||||
|
||||
class BASS_MIDI_MARK(ctypes.Structure):
|
||||
_fields_ = [('track', ctypes.c_ulong),#DWORD track; // track containing marker
|
||||
('pos', ctypes.c_ulong),#DWORD pos; // marker position (bytes)
|
||||
('text', ctypes.c_char_p)#const char *text; // marker text
|
||||
]
|
||||
|
||||
# Marker types
|
||||
BASS_MIDI_MARK_MARKER = 0 # marker events
|
||||
BASS_MIDI_MARK_CUE = 1 # cue events
|
||||
BASS_MIDI_MARK_LYRIC = 2 # lyric events
|
||||
BASS_MIDI_MARK_TEXT = 3 # text events
|
||||
BASS_MIDI_MARK_TIMESIG = 4 # time signature
|
||||
|
||||
# MIDI events
|
||||
MIDI_EVENT_NOTE = 1
|
||||
MIDI_EVENT_PROGRAM = 2
|
||||
MIDI_EVENT_CHANPRES = 3
|
||||
MIDI_EVENT_PITCH = 4
|
||||
MIDI_EVENT_PITCHRANGE = 5
|
||||
MIDI_EVENT_DRUMS = 6
|
||||
MIDI_EVENT_FINETUNE = 7
|
||||
MIDI_EVENT_COARSETUNE = 8
|
||||
MIDI_EVENT_MASTERVOL = 9
|
||||
MIDI_EVENT_BANK = 10
|
||||
MIDI_EVENT_MODULATION = 11
|
||||
MIDI_EVENT_VOLUME = 12
|
||||
MIDI_EVENT_PAN = 13
|
||||
MIDI_EVENT_EXPRESSION = 14
|
||||
MIDI_EVENT_SUSTAIN = 15
|
||||
MIDI_EVENT_SOUNDOFF = 16
|
||||
MIDI_EVENT_RESET = 17
|
||||
MIDI_EVENT_NOTESOFF = 18
|
||||
MIDI_EVENT_PORTAMENTO = 19
|
||||
MIDI_EVENT_PORTATIME = 20
|
||||
MIDI_EVENT_PORTANOTE = 21
|
||||
MIDI_EVENT_MODE = 22
|
||||
MIDI_EVENT_REVERB = 23
|
||||
MIDI_EVENT_CHORUS = 24
|
||||
MIDI_EVENT_CUTOFF = 25
|
||||
MIDI_EVENT_RESONANCE = 26
|
||||
MIDI_EVENT_RELEASE = 27
|
||||
MIDI_EVENT_ATTACK = 28
|
||||
MIDI_EVENT_REVERB_MACRO = 30
|
||||
MIDI_EVENT_CHORUS_MACRO = 31
|
||||
MIDI_EVENT_REVERB_TIME = 32
|
||||
MIDI_EVENT_REVERB_DELAY = 33
|
||||
MIDI_EVENT_REVERB_LOCUTOFF = 34
|
||||
MIDI_EVENT_REVERB_HICUTOFF = 35
|
||||
MIDI_EVENT_REVERB_LEVEL = 36
|
||||
MIDI_EVENT_CHORUS_DELAY = 37
|
||||
MIDI_EVENT_CHORUS_DEPTH = 38
|
||||
MIDI_EVENT_CHORUS_RATE = 39
|
||||
MIDI_EVENT_CHORUS_FEEDBACK = 40
|
||||
MIDI_EVENT_CHORUS_LEVEL = 41
|
||||
MIDI_EVENT_CHORUS_REVERB = 42
|
||||
MIDI_EVENT_DRUM_FINETUNE = 50
|
||||
MIDI_EVENT_DRUM_COARSETUNE = 51
|
||||
MIDI_EVENT_DRUM_PAN = 52
|
||||
MIDI_EVENT_DRUM_REVERB = 53
|
||||
MIDI_EVENT_DRUM_CHORUS = 54
|
||||
MIDI_EVENT_DRUM_CUTOFF = 55
|
||||
MIDI_EVENT_DRUM_RESONANCE = 56
|
||||
MIDI_EVENT_DRUM_LEVEL = 57
|
||||
MIDI_EVENT_TEMPO = 62
|
||||
MIDI_EVENT_MIXLEVEL = 0x10000
|
||||
MIDI_EVENT_TRANSPOSE = 0x10001
|
||||
|
||||
class BASS_MIDI_EVENT(ctypes.Structure):
|
||||
_fields_ = [('event', ctypes.c_ulong),#DWORD event; // MIDI_EVENT_xxx
|
||||
('param', ctypes.c_ulong),#DWORD param;
|
||||
('chan', ctypes.c_ulong),#DWORD chan;
|
||||
('tick', ctypes.c_ulong),#DWORD tick; // event position (ticks)
|
||||
('pos', ctypes.c_ulong)#DWORD pos; // event position (bytes)
|
||||
]
|
||||
|
||||
# BASS_CHANNELINFO type
|
||||
BASS_CTYPE_STREAM_MIDI = 0x10d00
|
||||
|
||||
# Additional attributes
|
||||
BASS_ATTRIB_MIDI_PPQN = 0x12000
|
||||
BASS_ATTRIB_MIDI_TRACK_VOL = 0x12100 # + track #
|
||||
|
||||
# Additional tag type
|
||||
BASS_TAG_MIDI_TRACK = 0x11000 # + track #, track text : array of null-terminated ANSI strings
|
||||
|
||||
# BASS_ChannelGetLength/GetPosition/SetPosition mode
|
||||
BASS_POS_MIDI_TICK = 2 # tick position
|
||||
|
||||
#HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreate)(DWORD channels, DWORD flags, DWORD freq);
|
||||
BASS_MIDI_StreamCreate = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong)(('BASS_MIDI_StreamCreate', bassmidi_module))
|
||||
#HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags, DWORD freq);
|
||||
BASS_MIDI_StreamCreateFile = func_type(HSTREAM, ctypes.c_byte, ctypes.c_void_p, QWORD, QWORD, ctypes.c_ulong, ctypes.c_ulong)(('BASS_MIDI_StreamCreateFile', bassmidi_module))
|
||||
#HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq);
|
||||
BASS_MIDI_StreamCreateURL = func_type(HSTREAM, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_ulong, DOWNLOADPROC, ctypes.c_void_p, ctypes.c_ulong)(('BASS_MIDI_StreamCreateURL', bassmidi_module))
|
||||
#HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user, DWORD freq);
|
||||
BASS_MIDI_StreamCreateFileUser = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_FILEPROCS), ctypes.c_void_p, ctypes.c_ulong)(('BASS_MIDI_StreamCreateFileUser', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_StreamGetMark)(HSTREAM handle, DWORD type, DWORD index, BASS_MIDI_MARK *mark);
|
||||
BASS_MIDI_StreamGetMark = func_type(ctypes.c_byte, HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_MIDI_MARK))(('BASS_MIDI_StreamGetMark', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFonts)(HSTREAM handle, const BASS_MIDI_FONT *fonts, DWORD count);
|
||||
BASS_MIDI_StreamSetFonts = func_type(ctypes.c_byte, HSTREAM, ctypes.POINTER(BASS_MIDI_FONT), ctypes.c_ulong)(('BASS_MIDI_StreamSetFonts', bassmidi_module))
|
||||
#DWORD BASSMIDIDEF(BASS_MIDI_StreamGetFonts)(HSTREAM handle, BASS_MIDI_FONT *fonts, DWORD count);
|
||||
BASS_MIDI_StreamGetFonts = func_type(ctypes.c_ulong, HSTREAM, ctypes.POINTER(BASS_MIDI_FONT), ctypes.c_ulong)(('BASS_MIDI_StreamGetFonts', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_StreamLoadSamples)(HSTREAM handle);
|
||||
BASS_MIDI_StreamLoadSamples = func_type(ctypes.c_byte, HSTREAM)(('BASS_MIDI_StreamLoadSamples', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_StreamEvent)(HSTREAM handle, DWORD chan, DWORD event, DWORD param);
|
||||
BASS_MIDI_StreamEvent = func_type(ctypes.c_byte, HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong)(('BASS_MIDI_StreamEvent', bassmidi_module))
|
||||
#DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvent)(HSTREAM handle, DWORD chan, DWORD event);
|
||||
BASS_MIDI_StreamGetEvent = func_type(ctypes.c_ulong, HSTREAM, ctypes.c_ulong, ctypes.c_ulong)(('BASS_MIDI_StreamGetEvent', bassmidi_module))
|
||||
#DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvents)(HSTREAM handle, DWORD track, DWORD filter, BASS_MIDI_EVENT *events);
|
||||
BASS_MIDI_StreamGetEvents = func_type(ctypes.c_ulong, HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_MIDI_EVENT))(('BASS_MIDI_StreamGetEvents', bassmidi_module))
|
||||
#HSTREAM BASSMIDIDEF(BASS_MIDI_StreamGetChannel)(HSTREAM handle, DWORD chan);
|
||||
BASS_MIDI_StreamGetChannel = func_type(HSTREAM, HSTREAM, ctypes.c_ulong)(('BASS_MIDI_StreamGetChannel', bassmidi_module))
|
||||
|
||||
#HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInit)(const void *file, DWORD flags);
|
||||
BASS_MIDI_FontInit = func_type(HSOUNDFONT, ctypes.c_void_p, ctypes.c_ulong)(('BASS_MIDI_FontInit', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_FontFree)(HSOUNDFONT handle);
|
||||
BASS_MIDI_FontFree = func_type(ctypes.c_byte, HSOUNDFONT)(('BASS_MIDI_FontFree', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_FontGetInfo)(HSOUNDFONT handle, BASS_MIDI_FONTINFO *info);
|
||||
BASS_MIDI_FontGetInfo = func_type(ctypes.c_byte, HSOUNDFONT, ctypes.POINTER(BASS_MIDI_FONTINFO))(('BASS_MIDI_FontGetInfo', bassmidi_module))
|
||||
#const char *BASSMIDIDEF(BASS_MIDI_FontGetPreset)(HSOUNDFONT handle, int preset, int bank);
|
||||
BASS_MIDI_FontGetPreset = func_type(ctypes.c_char_p, HSOUNDFONT, ctypes.c_int, ctypes.c_int)(('BASS_MIDI_FontGetPreset', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_FontLoad)(HSOUNDFONT handle, int preset, int bank);
|
||||
BASS_MIDI_FontLoad = func_type(ctypes.c_byte, HSOUNDFONT, ctypes.c_int, ctypes.c_int)(('BASS_MIDI_FontLoad', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_FontCompact)(HSOUNDFONT handle);
|
||||
BASS_MIDI_FontCompact = func_type(ctypes.c_byte, HSOUNDFONT)(('BASS_MIDI_FontCompact', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_FontPack)(HSOUNDFONT handle, const void *outfile, const void *encoder, DWORD flags);
|
||||
BASS_MIDI_FontPack = func_type(ctypes.c_byte, HSOUNDFONT, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_ulong)(('BASS_MIDI_FontPack', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_FontUnpack)(HSOUNDFONT handle, const void *outfile, DWORD flags);
|
||||
BASS_MIDI_FontUnpack = func_type(ctypes.c_byte, HSOUNDFONT, ctypes.c_void_p, ctypes.c_ulong)(('BASS_MIDI_FontUnpack', bassmidi_module))
|
||||
#BOOL BASSMIDIDEF(BASS_MIDI_FontSetVolume)(HSOUNDFONT handle, float volume);
|
||||
BASS_MIDI_FontSetVolume = func_type(ctypes.c_byte, HSOUNDFONT, ctypes.c_float)(('BASS_MIDI_FontSetVolume', bassmidi_module))
|
||||
#float BASSMIDIDEF(BASS_MIDI_FontGetVolume)(HSOUNDFONT handle);
|
||||
BASS_MIDI_FontGetVolume = func_type(ctypes.c_float, HSOUNDFONT)(('BASS_MIDI_FontGetVolume', bassmidi_module))
|
117
src/sound_lib/external/pybassmix.py
vendored
Normal file
117
src/sound_lib/external/pybassmix.py
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
from __future__ import absolute_import
|
||||
# Copyright(c) Max Kolosov 2009 maxkolosov@inbox.ru
|
||||
# http://vosolok2008.narod.ru
|
||||
# BSD license
|
||||
|
||||
__version__ = '0.1'
|
||||
__versionTime__ = '2009-11-15'
|
||||
__author__ = 'Max Kolosov <maxkolosov@inbox.ru>'
|
||||
__doc__ = '''
|
||||
pybassmix.py - is ctypes python module for
|
||||
BASSmix - extension to the BASS audio library, providing the ability
|
||||
to mix together multiple BASS channels, with resampling and matrix mixing
|
||||
features. It also provides the ability to go the other way and split a
|
||||
BASS channel into multiple channels.
|
||||
'''
|
||||
|
||||
import os, sys, ctypes, platform
|
||||
from . import pybass
|
||||
|
||||
QWORD = pybass.QWORD
|
||||
HSYNC = pybass.HSYNC
|
||||
HSTREAM = pybass.HSTREAM
|
||||
DOWNLOADPROC = pybass.DOWNLOADPROC
|
||||
SYNCPROC = pybass.SYNCPROC
|
||||
BASS_FILEPROCS = pybass.BASS_FILEPROCS
|
||||
|
||||
from .paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
bassmix_module = libloader.load_library('bassmix', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
|
||||
# additional BASS_SetConfig option
|
||||
BASS_CONFIG_MIXER_FILTER = 0x10600
|
||||
BASS_CONFIG_MIXER_BUFFER = 0x10601
|
||||
BASS_CONFIG_SPLIT_BUFFER = 0x10610
|
||||
|
||||
# BASS_Mixer_StreamCreate flags
|
||||
BASS_MIXER_END = 0x10000# end the stream when there are no sources
|
||||
BASS_MIXER_NONSTOP = 0x20000# don't stall when there are no sources
|
||||
BASS_MIXER_RESUME = 0x1000# resume stalled immediately upon new/unpaused source
|
||||
|
||||
# source flags
|
||||
BASS_MIXER_FILTER = 0x1000# resampling filter
|
||||
BASS_MIXER_BUFFER = 0x2000# buffer data for BASS_Mixer_ChannelGetData/Level
|
||||
BASS_MIXER_LIMIT = 0x4000# limit mixer processing to the amount available from this source
|
||||
BASS_MIXER_MATRIX = 0x10000# matrix mixing
|
||||
BASS_MIXER_PAUSE = 0x20000# don't process the source
|
||||
BASS_MIXER_DOWNMIX = 0x400000# downmix to stereo/mono
|
||||
BASS_MIXER_NORAMPIN = 0x800000# don't ramp-in the start
|
||||
|
||||
# envelope node
|
||||
class BASS_MIXER_NODE(ctypes.Structure):
|
||||
_fields_ = [('pos', ctypes.c_ulong),#QWORD pos;
|
||||
('value', ctypes.c_float)#float value;
|
||||
]
|
||||
|
||||
# envelope types
|
||||
BASS_MIXER_ENV_FREQ = 1
|
||||
BASS_MIXER_ENV_VOL = 2
|
||||
BASS_MIXER_ENV_PAN = 3
|
||||
BASS_MIXER_ENV_LOOP = 0x10000# FLAG: loop
|
||||
|
||||
# additional sync type
|
||||
BASS_SYNC_MIXER_ENVELOPE = 0x10200
|
||||
|
||||
# BASS_CHANNELINFO type
|
||||
BASS_CTYPE_STREAM_MIXER = 0x10800
|
||||
BASS_CTYPE_STREAM_SPLIT = 0x10801
|
||||
|
||||
|
||||
#DWORD BASSMIXDEF(BASS_Mixer_GetVersion)();
|
||||
BASS_Mixer_GetVersion = func_type(ctypes.c_ulong)(('BASS_Mixer_GetVersion', bassmix_module))
|
||||
|
||||
#HSTREAM BASSMIXDEF(BASS_Mixer_StreamCreate)(DWORD freq, DWORD chans, DWORD flags);
|
||||
BASS_Mixer_StreamCreate = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong)(('BASS_Mixer_StreamCreate', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_StreamAddChannel)(HSTREAM handle, DWORD channel, DWORD flags);
|
||||
BASS_Mixer_StreamAddChannel = func_type(ctypes.c_byte, HSTREAM, ctypes.c_ulong, ctypes.c_ulong)(('BASS_Mixer_StreamAddChannel', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_StreamAddChannelEx)(HSTREAM handle, DWORD channel, DWORD flags, QWORD start, QWORD length);
|
||||
BASS_Mixer_StreamAddChannelEx = func_type(ctypes.c_byte, HSTREAM, ctypes.c_ulong, ctypes.c_ulong, QWORD, QWORD)(('BASS_Mixer_StreamAddChannelEx', bassmix_module))
|
||||
|
||||
#HSTREAM BASSMIXDEF(BASS_Mixer_ChannelGetMixer)(DWORD handle);
|
||||
BASS_Mixer_ChannelGetMixer = func_type(HSTREAM, ctypes.c_ulong)(('BASS_Mixer_ChannelGetMixer', bassmix_module))
|
||||
#DWORD BASSMIXDEF(BASS_Mixer_ChannelFlags)(DWORD handle, DWORD flags, DWORD mask);
|
||||
BASS_Mixer_ChannelFlags = func_type(ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong)(('BASS_Mixer_ChannelFlags', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_ChannelRemove)(DWORD handle);
|
||||
BASS_Mixer_ChannelRemove = func_type(ctypes.c_byte, ctypes.c_ulong)(('BASS_Mixer_ChannelRemove', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode);
|
||||
BASS_Mixer_ChannelSetPosition = func_type(ctypes.c_byte, ctypes.c_ulong, QWORD, ctypes.c_ulong)(('BASS_Mixer_ChannelSetPosition', bassmix_module))
|
||||
#QWORD BASSMIXDEF(BASS_Mixer_ChannelGetPosition)(DWORD handle, DWORD mode);
|
||||
BASS_Mixer_ChannelGetPosition = func_type(QWORD, ctypes.c_ulong, ctypes.c_ulong)(('BASS_Mixer_ChannelGetPosition', bassmix_module))
|
||||
#DWORD BASSMIXDEF(BASS_Mixer_ChannelGetLevel)(DWORD handle);
|
||||
BASS_Mixer_ChannelGetLevel = func_type(ctypes.c_ulong, ctypes.c_ulong)(('BASS_Mixer_ChannelGetLevel', bassmix_module))
|
||||
#DWORD BASSMIXDEF(BASS_Mixer_ChannelGetData)(DWORD handle, void *buffer, DWORD length);
|
||||
BASS_Mixer_ChannelGetData = func_type(ctypes.c_ulong, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong)(('BASS_Mixer_ChannelGetData', bassmix_module))
|
||||
#HSYNC BASSMIXDEF(BASS_Mixer_ChannelSetSync)(DWORD handle, DWORD type, QWORD param, SYNCPROC *proc, void *user);
|
||||
BASS_Mixer_ChannelSetSync = func_type(HSYNC, ctypes.c_ulong, ctypes.c_ulong, QWORD, SYNCPROC, ctypes.c_void_p)(('BASS_Mixer_ChannelSetSync', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_ChannelRemoveSync)(DWORD channel, HSYNC sync);
|
||||
BASS_Mixer_ChannelRemoveSync = func_type(ctypes.c_byte, ctypes.c_ulong, HSYNC)(('BASS_Mixer_ChannelRemoveSync', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_ChannelSetMatrix)(DWORD handle, const float *matrix);
|
||||
BASS_Mixer_ChannelSetMatrix = func_type(ctypes.c_byte, ctypes.c_ulong, ctypes.POINTER(ctypes.c_float))(('BASS_Mixer_ChannelSetMatrix', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_ChannelGetMatrix)(DWORD handle, float *matrix);
|
||||
BASS_Mixer_ChannelGetMatrix = func_type(ctypes.c_byte, ctypes.c_ulong, ctypes.POINTER(ctypes.c_float))(('BASS_Mixer_ChannelGetMatrix', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_ChannelSetEnvelope)(DWORD handle, DWORD type, const BASS_MIXER_NODE *nodes, DWORD count);
|
||||
BASS_Mixer_ChannelSetEnvelope = func_type(ctypes.c_byte, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_MIXER_NODE), ctypes.c_ulong)(('BASS_Mixer_ChannelSetEnvelope', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Mixer_ChannelSetEnvelopePos)(DWORD handle, DWORD type, QWORD pos);
|
||||
BASS_Mixer_ChannelSetEnvelopePos = func_type(ctypes.c_byte, ctypes.c_ulong, ctypes.c_ulong, QWORD)(('BASS_Mixer_ChannelSetEnvelopePos', bassmix_module))
|
||||
#QWORD BASSMIXDEF(BASS_Mixer_ChannelGetEnvelopePos)(DWORD handle, DWORD type, float *value);
|
||||
BASS_Mixer_ChannelGetEnvelopePos = func_type(QWORD, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_float)(('BASS_Mixer_ChannelGetEnvelopePos', bassmix_module))
|
||||
|
||||
#HSTREAM BASSMIXDEF(BASS_Split_StreamCreate)(DWORD channel, DWORD flags, int *chanmap);
|
||||
BASS_Split_StreamCreate = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_int)(('BASS_Split_StreamCreate', bassmix_module))
|
||||
#DWORD BASSMIXDEF(BASS_Split_StreamGetSource)(HSTREAM handle);
|
||||
BASS_Split_StreamGetSource = func_type(ctypes.c_ulong, HSTREAM)(('BASS_Split_StreamGetSource', bassmix_module))
|
||||
#BOOL BASSMIXDEF(BASS_Split_StreamReset)(DWORD handle);
|
||||
BASS_Split_StreamReset = func_type(ctypes.c_byte, ctypes.c_ulong)(('BASS_Split_StreamReset', bassmix_module))
|
||||
|
47
src/sound_lib/external/pybassopus.py
vendored
Normal file
47
src/sound_lib/external/pybassopus.py
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
# Copyright(c) Max Kolosov 2009 maxkolosov@inbox.ru
|
||||
# http://vosolok2008.narod.ru
|
||||
# BSD license
|
||||
|
||||
__version__ = '0.1'
|
||||
__versionTime__ = '2009-11-15'
|
||||
__author__ = 'Max Kolosov <maxkolosov@inbox.ru>'
|
||||
__doc__ = '''
|
||||
pybassflac.py - is ctypes python module for
|
||||
BASSFLAC - extension to the BASS audio library,
|
||||
enabling the playing of FLAC (Free Lossless Audio Codec) encoded files.
|
||||
'''
|
||||
|
||||
import os, sys, ctypes, pybass
|
||||
from paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
bassopus_module = libloader.load_library('bassopus', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
#Register the plugin with the Bass plugin system.
|
||||
pybass.BASS_PluginLoad(libloader.find_library_path('bassopus', x86_path=x86_path, x64_path=x64_path), 0)
|
||||
|
||||
QWORD = pybass.QWORD
|
||||
HSTREAM = pybass.HSTREAM
|
||||
DOWNLOADPROC = pybass.DOWNLOADPROC
|
||||
BASS_FILEPROCS = pybass.BASS_FILEPROCS
|
||||
|
||||
# BASS_CHANNELINFO type
|
||||
BASS_CTYPE_STREAM_OPUS = 0x11200
|
||||
|
||||
|
||||
#HSTREAM BASSOPUSDEF(BASS_OPUS_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
|
||||
BASS_OPUS_StreamCreateFile = func_type(HSTREAM, ctypes.c_byte, ctypes.c_void_p, QWORD, QWORD, ctypes.c_ulong)(('BASS_OPUS_StreamCreateFile', bassopus_module))
|
||||
#HSTREAM BASSFLACDEF(BASS_FLAC_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user);
|
||||
BASS_OPUS_StreamCreateURL = func_type(HSTREAM, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_ulong, DOWNLOADPROC, ctypes.c_void_p)(('BASS_OPUS_StreamCreateURL', bassopus_module))
|
||||
#HSTREAM BASSFLACDEF(BASS_FLAC_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user);
|
||||
BASS_OPUS_StreamCreateFileUser = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_FILEPROCS), ctypes.c_void_p)(('BASS_OPUS_StreamCreateFileUser', bassopus_module))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if not pybass.BASS_Init(-1, 44100, 0, 0, 0):
|
||||
print 'BASS_Init error', pybass.get_error_description(pybass.BASS_ErrorGetCode())
|
||||
else:
|
||||
handle = BASS_OPUS_StreamCreateFile(False, 'test.opus', 0, 0, 0)
|
||||
pybass.play_handle(handle)
|
||||
if not pybass.BASS_Free():
|
||||
print 'BASS_Free error', pybass.get_error_description(pybass.BASS_ErrorGetCode())
|
148
src/sound_lib/external/pybasswma.py
vendored
Normal file
148
src/sound_lib/external/pybasswma.py
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
from __future__ import absolute_import
|
||||
# Copyright(c) Max Kolosov 2009 maxkolosov@inbox.ru
|
||||
# http://vosolok2008.narod.ru
|
||||
# BSD license
|
||||
|
||||
__version__ = '0.1'
|
||||
__versionTime__ = '2009-11-15'
|
||||
__author__ = 'Max Kolosov <maxkolosov@inbox.ru>'
|
||||
__doc__ = '''
|
||||
pybasswma.py - is ctypes python module for
|
||||
BASSWMA - extension to the BASS audio library,
|
||||
enabling the playback of WMA files and network streams.
|
||||
The audio tracks of WMV files can also be played.
|
||||
WMA file encoding and network broadcasting functions are also provided.
|
||||
|
||||
Requirements
|
||||
============
|
||||
BASS 2.4 is required. The Windows Media Format modules (v9 or above) are
|
||||
also required to be installed on the user's system. They are installed with
|
||||
Windows Media player, so will already be on most users' systems, but they
|
||||
can also be installed separately (WMFDIST.EXE is available from the BASS website).
|
||||
'''
|
||||
|
||||
import os, sys, ctypes
|
||||
from sound_lib.external import pybass
|
||||
|
||||
from .paths import x86_path, x64_path
|
||||
import libloader
|
||||
|
||||
QWORD = pybass.QWORD
|
||||
HSTREAM = pybass.HSTREAM
|
||||
BASS_FILEPROCS = pybass.BASS_FILEPROCS
|
||||
|
||||
HWMENCODE = ctypes.c_ulong# WMA encoding handle
|
||||
|
||||
basswma_module = libloader.load_library('basswma', x86_path=x86_path, x64_path=x64_path)
|
||||
func_type = libloader.get_functype()
|
||||
#Register the plugin with the Bass plugin system.
|
||||
pybass.BASS_PluginLoad(libloader.find_library_path('basswma', x86_path=x86_path, x64_path=x64_path), 0)
|
||||
|
||||
|
||||
# Additional error codes returned by BASS_ErrorGetCode
|
||||
BASS_ERROR_WMA_LICENSE = 1000# the file is protected
|
||||
BASS_ERROR_WMA = 1001# Windows Media (9 or above) is not installed
|
||||
BASS_ERROR_WMA_WM9 = BASS_ERROR_WMA
|
||||
BASS_ERROR_WMA_DENIED = 1002# access denied (user/pass is invalid)
|
||||
BASS_ERROR_WMA_INDIVIDUAL = 1004# individualization is needed
|
||||
BASS_ERROR_WMA_PUBINIT = 1005# publishing point initialization problem
|
||||
|
||||
# Additional BASS_SetConfig options
|
||||
BASS_CONFIG_WMA_PRECHECK = 0x10100
|
||||
BASS_CONFIG_WMA_PREBUF = 0x10101
|
||||
BASS_CONFIG_WMA_BASSFILE = 0x10103
|
||||
BASS_CONFIG_WMA_NETSEEK = 0x10104
|
||||
BASS_CONFIG_WMA_VIDEO = 0x10105
|
||||
|
||||
# additional WMA sync types
|
||||
BASS_SYNC_WMA_CHANGE = 0x10100
|
||||
BASS_SYNC_WMA_META = 0x10101
|
||||
|
||||
# additional BASS_StreamGetFilePosition WMA mode
|
||||
BASS_FILEPOS_WMA_BUFFER = 1000# internet buffering progress (0-100%)
|
||||
|
||||
# Additional flags for use with BASS_WMA_EncodeOpen/File/Network/Publish
|
||||
BASS_WMA_ENCODE_STANDARD = 0x2000# standard WMA
|
||||
BASS_WMA_ENCODE_PRO = 0x4000# WMA Pro
|
||||
BASS_WMA_ENCODE_24BIT = 0x8000# 24-bit
|
||||
BASS_WMA_ENCODE_SCRIPT = 0x20000# set script (mid-stream tags) in the WMA encoding
|
||||
|
||||
# Additional flag for use with BASS_WMA_EncodeGetRates
|
||||
BASS_WMA_ENCODE_RATES_VBR = 0x10000# get available VBR quality settings
|
||||
|
||||
#typedef void (CALLBACK CLIENTCONNECTPROC)(HWMENCODE handle, BOOL connect, const char *ip, void *user);
|
||||
CLIENTCONNECTPROC = func_type(None, HWMENCODE, ctypes.c_byte, ctypes.c_char_p, ctypes.c_void_p)
|
||||
# Client connection notification callback function.
|
||||
#handle : The encoder
|
||||
#connect: TRUE=client is connecting, FALSE=disconnecting
|
||||
#ip : The client's IP (xxx.xxx.xxx.xxx:port)
|
||||
#user : The 'user' parameter value given when calling BASS_WMA_EncodeSetNotify
|
||||
|
||||
#typedef void (CALLBACK WMENCODEPROC)(HWMENCODE handle, DWORD type, const void *buffer, DWORD length, void *user);
|
||||
WMENCODEPROC = func_type(None, HWMENCODE, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_void_p)
|
||||
# Encoder callback function.
|
||||
#handle : The encoder handle
|
||||
#type : The type of data, one of BASS_WMA_ENCODE_xxx values
|
||||
#buffer : The encoded data
|
||||
#length : Length of the data
|
||||
#user : The 'user' parameter value given when calling BASS_WMA_EncodeOpen
|
||||
|
||||
# WMENCODEPROC "type" values
|
||||
BASS_WMA_ENCODE_HEAD = 0
|
||||
BASS_WMA_ENCODE_DATA = 1
|
||||
BASS_WMA_ENCODE_DONE = 2
|
||||
|
||||
# BASS_WMA_EncodeSetTag "form" values
|
||||
BASS_WMA_TAG_ANSI = 0
|
||||
BASS_WMA_TAG_UNICODE = 1
|
||||
BASS_WMA_TAG_UTF8 = 2
|
||||
BASS_WMA_TAG_BINARY = 0x100# FLAG: binary tag (HIWORD=length)
|
||||
|
||||
# BASS_CHANNELINFO type
|
||||
BASS_CTYPE_STREAM_WMA = 0x10300
|
||||
BASS_CTYPE_STREAM_WMA_MP3 = 0x10301
|
||||
|
||||
# Additional BASS_ChannelGetTags types
|
||||
BASS_TAG_WMA = 8# WMA header tags : series of null-terminated UTF-8 strings
|
||||
BASS_TAG_WMA_META = 11# WMA mid-stream tag : UTF-8 string
|
||||
|
||||
|
||||
#HSTREAM BASSWMADEF(BASS_WMA_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
|
||||
BASS_WMA_StreamCreateFile = func_type(HSTREAM, ctypes.c_byte, ctypes.c_void_p, QWORD, QWORD, ctypes.c_ulong)(('BASS_WMA_StreamCreateFile', basswma_module))
|
||||
#HSTREAM BASSWMADEF(BASS_WMA_StreamCreateFileAuth)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags, const char *user, const char *pass);
|
||||
BASS_WMA_StreamCreateFileAuth = func_type(HSTREAM, ctypes.c_byte, ctypes.c_void_p, QWORD, QWORD, ctypes.c_ulong, ctypes.c_char_p, ctypes.c_char_p)(('BASS_WMA_StreamCreateFileAuth', basswma_module))
|
||||
#HSTREAM BASSWMADEF(BASS_WMA_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user);
|
||||
BASS_WMA_StreamCreateFileUser = func_type(HSTREAM, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_FILEPROCS), ctypes.c_void_p)(('BASS_WMA_StreamCreateFileUser', basswma_module))
|
||||
|
||||
#const char *BASSWMADEF(BASS_WMA_GetTags)(const void *file, DWORD flags);
|
||||
BASS_WMA_GetTags = func_type(ctypes.c_char_p, ctypes.c_void_p, ctypes.c_ulong)(('BASS_WMA_GetTags', basswma_module))
|
||||
|
||||
#const DWORD *BASSWMADEF(BASS_WMA_EncodeGetRates)(DWORD freq, DWORD chans, DWORD flags);
|
||||
BASS_WMA_EncodeGetRates = func_type(ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong)(('BASS_WMA_EncodeGetRates', basswma_module))
|
||||
#HWMENCODE BASSWMADEF(BASS_WMA_EncodeOpen)(DWORD freq, DWORD chans, DWORD flags, DWORD bitrate, WMENCODEPROC *proc, void *user);
|
||||
BASS_WMA_EncodeOpen = func_type(HWMENCODE, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, WMENCODEPROC, ctypes.c_void_p)(('BASS_WMA_EncodeOpen', basswma_module))
|
||||
#HWMENCODE BASSWMADEF(BASS_WMA_EncodeOpenFile)(DWORD freq, DWORD chans, DWORD flags, DWORD bitrate, const char *file);
|
||||
BASS_WMA_EncodeOpenFile = func_type(HWMENCODE, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_char_p)(('BASS_WMA_EncodeOpenFile', basswma_module))
|
||||
#HWMENCODE BASSWMADEF(BASS_WMA_EncodeOpenNetwork)(DWORD freq, DWORD chans, DWORD flags, DWORD bitrate, DWORD port, DWORD clients);
|
||||
BASS_WMA_EncodeOpenNetwork = func_type(HWMENCODE, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong)(('BASS_WMA_EncodeOpenNetwork', basswma_module))
|
||||
#HWMENCODE BASSWMADEF(BASS_WMA_EncodeOpenNetworkMulti)(DWORD freq, DWORD chans, DWORD flags, const DWORD *bitrates, DWORD port, DWORD clients);
|
||||
BASS_WMA_EncodeOpenNetworkMulti = func_type(HWMENCODE, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_ulong), ctypes.c_ulong, ctypes.c_ulong)(('BASS_WMA_EncodeOpenNetworkMulti', basswma_module))
|
||||
#HWMENCODE BASSWMADEF(BASS_WMA_EncodeOpenPublish)(DWORD freq, DWORD chans, DWORD flags, DWORD bitrate, const char *url, const char *user, const char *pass);
|
||||
BASS_WMA_EncodeOpenPublish = func_type(HWMENCODE, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p)(('BASS_WMA_EncodeOpenPublish', basswma_module))
|
||||
#HWMENCODE BASSWMADEF(BASS_WMA_EncodeOpenPublishMulti)(DWORD freq, DWORD chans, DWORD flags, const DWORD *bitrates, const char *url, const char *user, const char *pass);
|
||||
BASS_WMA_EncodeOpenPublishMulti = func_type(HWMENCODE, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_ulong), ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p)(('BASS_WMA_EncodeOpenPublishMulti', basswma_module))
|
||||
#DWORD BASSWMADEF(BASS_WMA_EncodeGetPort)(HWMENCODE handle);
|
||||
BASS_WMA_EncodeGetPort = func_type(ctypes.c_ulong, HWMENCODE)(('BASS_WMA_EncodeGetPort', basswma_module))
|
||||
#BOOL BASSWMADEF(BASS_WMA_EncodeSetNotify)(HWMENCODE handle, CLIENTCONNECTPROC *proc, void *user);
|
||||
BASS_WMA_EncodeSetNotify = func_type(ctypes.c_byte, HWMENCODE, CLIENTCONNECTPROC, ctypes.c_void_p)(('BASS_WMA_EncodeSetNotify', basswma_module))
|
||||
#DWORD BASSWMADEF(BASS_WMA_EncodeGetClients)(HWMENCODE handle);
|
||||
BASS_WMA_EncodeGetClients = func_type(ctypes.c_ulong, HWMENCODE)(('BASS_WMA_EncodeGetClients', basswma_module))
|
||||
#BOOL BASSWMADEF(BASS_WMA_EncodeSetTag)(HWMENCODE handle, const char *tag, const char *text, DWORD form);
|
||||
BASS_WMA_EncodeSetTag = func_type(ctypes.c_byte, HWMENCODE, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_ulong)(('BASS_WMA_EncodeSetTag', basswma_module))
|
||||
#BOOL BASSWMADEF(BASS_WMA_EncodeWrite)(HWMENCODE handle, const void *buffer, DWORD length);
|
||||
BASS_WMA_EncodeWrite = func_type(ctypes.c_byte, HWMENCODE, ctypes.c_void_p, ctypes.c_ulong)(('BASS_WMA_EncodeWrite', basswma_module))
|
||||
#BOOL BASSWMADEF(BASS_WMA_EncodeClose)(HWMENCODE handle);
|
||||
BASS_WMA_EncodeClose = func_type(ctypes.c_byte, HWMENCODE)(('BASS_WMA_EncodeClose', basswma_module))
|
||||
|
||||
#void *BASSWMADEF(BASS_WMA_GetWMObject)(DWORD handle);
|
||||
BASS_WMA_GetWMObject = func_type(ctypes.c_void_p, ctypes.c_ulong)(('BASS_WMA_GetWMObject', basswma_module))
|
91
src/sound_lib/external/test_pybass.py
vendored
Normal file
91
src/sound_lib/external/test_pybass.py
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
from __future__ import print_function
|
||||
from future.builtins import hex
|
||||
from .pybass import *
|
||||
|
||||
def play_handle(handle, show_tags = True):
|
||||
if handle == 0:
|
||||
print(('BASS_StreamCreateFile error', get_error_description(BASS_ErrorGetCode())))
|
||||
else:
|
||||
if show_tags:
|
||||
print('============== Tags Information ==============')
|
||||
try:
|
||||
import pytags
|
||||
print((pytags.TAGS_Read(handle, '%IFV1(%ITRM(%TRCK),%ITRM(%TRCK). )%IFV2(%ITRM(%ARTI),%ICAP(%ITRM(%ARTI)),no artist) - %IFV2(%ITRM(%TITL),%ICAP(%ITRM(%TITL)),no title)%IFV1(%ITRM(%ALBM), - %IUPC(%ITRM(%ALBM)))%IFV1(%YEAR, %(%YEAR%))%IFV1(%ITRM(%GNRE), {%ITRM(%GNRE)})%IFV1(%ITRM(%CMNT), [%ITRM(%CMNT)])')))
|
||||
except:
|
||||
print('============== tags module not accessible ==============')
|
||||
print('============== BASS_ChannelGetTags return ==============')
|
||||
for tag in get_tags(handle):
|
||||
print(tag)
|
||||
for key, value in get_tags_as_dict(handle).items():
|
||||
print((key, ':', value))
|
||||
print('============== Channel Information ==============')
|
||||
channel_info = BASS_CHANNELINFO()
|
||||
if not BASS_ChannelGetInfo(handle, channel_info):
|
||||
print(('BASS_ChannelGetInfo error', get_error_description(BASS_ErrorGetCode())))
|
||||
else:
|
||||
print(('default playback rate =', channel_info.freq))
|
||||
print(('channels =', channel_info.chans))
|
||||
print(('BASS_SAMPLE/STREAM/MUSIC/SPEAKER flags =', channel_info.flags))
|
||||
print(('type of channel =', hex(channel_info.ctype)))
|
||||
print(('original resolution =', channel_info.origres))
|
||||
print(('plugin =', channel_info.plugin))
|
||||
print(('sample =', channel_info.sample))
|
||||
print(('filename =', channel_info.filename))
|
||||
print('============== Ext Channel Information ==============')
|
||||
channel_length = BASS_ChannelGetLength(handle, BASS_POS_BYTE)
|
||||
channel_position = BASS_ChannelGetPosition(handle, BASS_POS_BYTE)
|
||||
print(('Channel Length =', channel_length))
|
||||
print(('Channel Length =', int(BASS_ChannelBytes2Seconds(handle, channel_length)), 'seconds'))
|
||||
import time
|
||||
if not BASS_ChannelPlay(handle, False):
|
||||
print(('BASS_ChannelPlay error', get_error_description(BASS_ErrorGetCode())))
|
||||
else:
|
||||
print('============== Play Information ==============')
|
||||
while channel_position < channel_length:
|
||||
channel_position = BASS_ChannelGetPosition(handle, BASS_POS_BYTE)
|
||||
print(('Channel Position =', channel_position))
|
||||
print(('Channel Position =', int(BASS_ChannelBytes2Seconds(handle, channel_position)), 'seconds'))
|
||||
print(('CPU =', BASS_GetCPU()))
|
||||
time.sleep(1)
|
||||
if not BASS_StreamFree(handle):
|
||||
print(('BASS_StreamFree error', get_error_description(BASS_ErrorGetCode())))
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(('BASS implemented Version', BASSVERSIONTEXT))
|
||||
print(('BASS real Version', hex(BASS_GetVersion())))
|
||||
if not BASS_Init(-1, 44100, 0, 0, 0):
|
||||
print(('BASS_Init error', get_error_description(BASS_ErrorGetCode())))
|
||||
else:
|
||||
print('============== BASS Information ==============')
|
||||
bi = BASS_INFO()
|
||||
if not BASS_GetInfo(bi):
|
||||
print(('BASS_GetInfo error', get_error_description(BASS_ErrorGetCode())))
|
||||
else:
|
||||
print(('device capabilities (DSCAPS_xxx flags) =', bi.flags))
|
||||
print(('size of total device hardware memory =', bi.hwsize))
|
||||
print(('size of free device hardware memory =', bi.hwfree))
|
||||
print(('number of free sample slots in the hardware =', bi.freesam))
|
||||
print(('number of free 3D sample slots in the hardware =', bi.free3d))
|
||||
print(('min sample rate supported by the hardware =', bi.minrate))
|
||||
print(('max sample rate supported by the hardware =', bi.maxrate))
|
||||
print(('device supports EAX? (always FALSE if BASS_DEVICE_3D was not used) =', bool(bi.eax)))
|
||||
print(('recommended minimum buffer length in ms (requires BASS_DEVICE_LATENCY) =', bi.minbuf))
|
||||
print(('DirectSound version =', bi.dsver))
|
||||
print(('delay (in ms) before start of playback (requires BASS_DEVICE_LATENCY) =', bi.latency))
|
||||
print(('BASS_Init "flags" parameter =', bi.initflags))
|
||||
print(('number of speakers available', bi.speakers))
|
||||
print(('current output rate (Vista/OSX only) =', bi.freq))
|
||||
print('============== volume ==============')
|
||||
print(('volume =', BASS_GetVolume()))
|
||||
print('============== Device Information ==============')
|
||||
bd = BASS_DEVICEINFO()
|
||||
if not BASS_GetDeviceInfo(BASS_GetDevice(), bd):
|
||||
print(('BASS_GetDeviceInfo error', get_error_description(BASS_ErrorGetCode())))
|
||||
else:
|
||||
print(('description =', bd.name))
|
||||
print(('driver =', bd.driver))
|
||||
print(('flags =', bd.flags))
|
||||
handle = BASS_StreamCreateFile(False, 'test.ogg', 0, 0, 0)
|
||||
play_handle(handle)
|
||||
if not BASS_Free():
|
||||
print(('BASS_Free error', get_error_description(BASS_ErrorGetCode())))
|
66
src/sound_lib/input.py
Normal file
66
src/sound_lib/input.py
Normal file
@ -0,0 +1,66 @@
|
||||
from __future__ import absolute_import
|
||||
from future.builtins import object
|
||||
from ctypes import string_at
|
||||
import wave
|
||||
|
||||
from .external.pybass import *
|
||||
from . import config
|
||||
from .main import bass_call, bass_call_0, BassError
|
||||
|
||||
class Input (object):
|
||||
|
||||
def __init__ (self, device=-1):
|
||||
try:
|
||||
bass_call(BASS_RecordInit, device)
|
||||
except BassError:
|
||||
pass
|
||||
self._device = device
|
||||
self.config = config.BassConfig()
|
||||
|
||||
def free(self):
|
||||
"""Frees all resources used by the recording device."""
|
||||
return bass_call(BASS_RecordFree)
|
||||
|
||||
def get_device(self):
|
||||
return bass_call_0(BASS_RecordGetDevice)
|
||||
|
||||
def set_device(self, device):
|
||||
if device == self._device:
|
||||
return
|
||||
self.free()
|
||||
self.__init__(device=device)
|
||||
|
||||
device = property(fget=get_device, fset=set_device)
|
||||
|
||||
@staticmethod
|
||||
def get_device_names():
|
||||
"""Convenience method that returns a list of device names that are considered
|
||||
valid by bass.
|
||||
|
||||
Parameters: none.
|
||||
returns: list of devices, 0-indexed.
|
||||
"""
|
||||
result = ['Default']
|
||||
info = BASS_DEVICEINFO()
|
||||
count = 0
|
||||
while BASS_RecordGetDeviceInfo(count, ctypes.byref(info)):
|
||||
if info.flags & BASS_DEVICE_ENABLED:
|
||||
retrieved = info.name
|
||||
if platform.system() == 'Windows':
|
||||
retrieved = retrieved.decode('mbcs')
|
||||
retrieved = retrieved.replace('(', '').replace(')', '').strip()
|
||||
result.append(retrieved)
|
||||
count += 1
|
||||
return result
|
||||
|
||||
def find_device_by_name(self, name):
|
||||
return self.get_device_names().index(name) - 1
|
||||
|
||||
def find_default_device(self):
|
||||
return -1
|
||||
|
||||
def find_user_provided_device(self, device_name):
|
||||
try:
|
||||
return self.find_device_by_name(device_name)
|
||||
except ValueError:
|
||||
return self.find_default_device()
|
BIN
src/sound_lib/lib/x64/bass.dll
Normal file
BIN
src/sound_lib/lib/x64/bass.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/bass_aac.dll
Normal file
BIN
src/sound_lib/lib/x64/bass_aac.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/bass_alac.dll
Normal file
BIN
src/sound_lib/lib/x64/bass_alac.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/bass_fx.dll
Normal file
BIN
src/sound_lib/lib/x64/bass_fx.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/bassflac.dll
Normal file
BIN
src/sound_lib/lib/x64/bassflac.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/bassmidi.dll
Normal file
BIN
src/sound_lib/lib/x64/bassmidi.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/bassmix.dll
Normal file
BIN
src/sound_lib/lib/x64/bassmix.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/bassopus.dll
Normal file
BIN
src/sound_lib/lib/x64/bassopus.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/basswma.dll
Normal file
BIN
src/sound_lib/lib/x64/basswma.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbass.dylib
Normal file
BIN
src/sound_lib/lib/x64/libbass.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbass.so
Normal file
BIN
src/sound_lib/lib/x64/libbass.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbass_aac.so
Normal file
BIN
src/sound_lib/lib/x64/libbass_aac.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbass_alac.so
Normal file
BIN
src/sound_lib/lib/x64/libbass_alac.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbass_fx.dylib
Normal file
BIN
src/sound_lib/lib/x64/libbass_fx.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbass_fx.so
Normal file
BIN
src/sound_lib/lib/x64/libbass_fx.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbassenc.so
Normal file
BIN
src/sound_lib/lib/x64/libbassenc.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbassflac.so
Normal file
BIN
src/sound_lib/lib/x64/libbassflac.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbassmidi.so
Normal file
BIN
src/sound_lib/lib/x64/libbassmidi.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbassmix.so
Normal file
BIN
src/sound_lib/lib/x64/libbassmix.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbassopus.dylib
Normal file
BIN
src/sound_lib/lib/x64/libbassopus.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x64/libbassopus.so
Normal file
BIN
src/sound_lib/lib/x64/libbassopus.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bass.dll
Normal file
BIN
src/sound_lib/lib/x86/bass.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bass_aac.dll
Normal file
BIN
src/sound_lib/lib/x86/bass_aac.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bass_alac.dll
Normal file
BIN
src/sound_lib/lib/x86/bass_alac.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bass_fx.dll
Normal file
BIN
src/sound_lib/lib/x86/bass_fx.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bassenc.dll
Normal file
BIN
src/sound_lib/lib/x86/bassenc.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bassflac.dll
Normal file
BIN
src/sound_lib/lib/x86/bassflac.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bassmidi.dll
Normal file
BIN
src/sound_lib/lib/x86/bassmidi.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bassmix.dll
Normal file
BIN
src/sound_lib/lib/x86/bassmix.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/bassopus.dll
Normal file
BIN
src/sound_lib/lib/x86/bassopus.dll
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbass.dylib
Normal file
BIN
src/sound_lib/lib/x86/libbass.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbass.so
Normal file
BIN
src/sound_lib/lib/x86/libbass.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbass_aac.dylib
Normal file
BIN
src/sound_lib/lib/x86/libbass_aac.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbass_aac.so
Normal file
BIN
src/sound_lib/lib/x86/libbass_aac.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbass_alac.so
Normal file
BIN
src/sound_lib/lib/x86/libbass_alac.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbass_fx.dylib
Normal file
BIN
src/sound_lib/lib/x86/libbass_fx.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbass_fx.so
Normal file
BIN
src/sound_lib/lib/x86/libbass_fx.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassenc.dylib
Normal file
BIN
src/sound_lib/lib/x86/libbassenc.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassenc.so
Normal file
BIN
src/sound_lib/lib/x86/libbassenc.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassflac.dylib
Normal file
BIN
src/sound_lib/lib/x86/libbassflac.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassflac.so
Normal file
BIN
src/sound_lib/lib/x86/libbassflac.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassmidi.dylib
Normal file
BIN
src/sound_lib/lib/x86/libbassmidi.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassmidi.so
Normal file
BIN
src/sound_lib/lib/x86/libbassmidi.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassmix.dylib
Normal file
BIN
src/sound_lib/lib/x86/libbassmix.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassmix.so
Normal file
BIN
src/sound_lib/lib/x86/libbassmix.so
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassopus.dylib
Normal file
BIN
src/sound_lib/lib/x86/libbassopus.dylib
Normal file
Binary file not shown.
BIN
src/sound_lib/lib/x86/libbassopus.so
Normal file
BIN
src/sound_lib/lib/x86/libbassopus.so
Normal file
Binary file not shown.
100
src/sound_lib/listener.py
Normal file
100
src/sound_lib/listener.py
Normal file
@ -0,0 +1,100 @@
|
||||
from __future__ import absolute_import
|
||||
from future.builtins import object
|
||||
from ctypes import pointer
|
||||
from functools import partial
|
||||
from .main import bass_call, update_3d_system
|
||||
from .external.pybass import *
|
||||
|
||||
def _getter(base_prop, attr, obj):
|
||||
return getattr(getattr(obj, base_prop), attr)
|
||||
|
||||
def _setter(base_prop, subattr, obj, val):
|
||||
old = getattr(obj, base_prop)
|
||||
setattr(old, subattr, val)
|
||||
setattr(obj, base_prop, old)
|
||||
|
||||
class Listener(object):
|
||||
|
||||
def get_3d_position(self):
|
||||
res = {
|
||||
'position': BASS_3DVECTOR(),
|
||||
'velocity': BASS_3DVECTOR(),
|
||||
'front': BASS_3DVECTOR(),
|
||||
'top': BASS_3DVECTOR()
|
||||
}
|
||||
bass_call(BASS_Get3DPosition, pointer(res['position']), pointer(res['velocity']), pointer(res['front']), pointer(res['top']))
|
||||
return res
|
||||
|
||||
@update_3d_system
|
||||
def set_3d_position(self, position=None, velocity=None, front=None, top=None):
|
||||
"""Sets the position, velocity, and orientation of the listener (ie. the player)."""
|
||||
old = self.get_3d_position()
|
||||
if position is None:
|
||||
position = old['position']
|
||||
if velocity is None:
|
||||
velocity = old['velocity']
|
||||
if front is None:
|
||||
front = old['front']
|
||||
if top is None:
|
||||
top = old['top']
|
||||
position = pointer(position)
|
||||
velocity = pointer(velocity)
|
||||
front = pointer(front)
|
||||
top = pointer(top)
|
||||
bass_call(BASS_Set3DPosition, position, velocity, front, top)
|
||||
|
||||
def get_position(self):
|
||||
return self.get_3d_position()['position']
|
||||
|
||||
def set_position(self, position):
|
||||
self.set_3d_position(position=position)
|
||||
|
||||
position = property(fget=get_position, fset=set_position)
|
||||
|
||||
x = property(fget=partial(_getter, 'position', 'x'), fset=partial(_setter, 'position', 'x'))
|
||||
|
||||
y = property(fget=partial(_getter, 'position', 'y'), fset=partial(_setter, 'position', 'y'))
|
||||
|
||||
z = property(fget=partial(_getter, 'position', 'z'), fset=partial(_setter, 'position', 'z'))
|
||||
|
||||
def get_velocity(self):
|
||||
return self.get_3d_position()['velocity']
|
||||
|
||||
def set_velocity(self, velocity):
|
||||
self.set_3d_position(velocity=velocity)
|
||||
|
||||
velocity = property(fget=get_velocity, fset=set_velocity)
|
||||
|
||||
x_velocity = property(fget=partial(_getter, 'velocity', 'x'), fset=partial(_setter, 'velocity', 'x'))
|
||||
|
||||
y_velocity = property(fget=partial(_getter, 'velocity', 'y'), fset=partial(_setter, 'velocity', 'y'))
|
||||
|
||||
z_velocity = property(fget=partial(_getter, 'velocity', 'z'), fset=partial(_setter, 'velocity', 'z'))
|
||||
|
||||
def get_front(self):
|
||||
return self.get_3d_position()['front']
|
||||
|
||||
def set_front(self, front):
|
||||
self.set_3d_position(front=front)
|
||||
|
||||
front = property(fget=get_front, fset=set_front)
|
||||
|
||||
front_x = property(fget=partial(_getter, 'front', 'x'), fset=partial(_setter, 'front', 'x'))
|
||||
|
||||
front_y = property(fget=partial(_getter, 'front', 'y'), fset=partial(_setter, 'front', 'y'))
|
||||
|
||||
front_z = property(fget=partial(_getter, 'front', 'z'), fset=partial(_setter, 'front', 'z'))
|
||||
|
||||
def get_top(self):
|
||||
return self.get_3d_position()['top']
|
||||
|
||||
def set_top(self, top):
|
||||
self.set_3d_position(top=top)
|
||||
|
||||
top = property(fget=get_top, fset=set_top)
|
||||
|
||||
top_x = property(fget=partial(_getter, 'front', 'x'), fset=partial(_setter, 'front', 'x'))
|
||||
|
||||
top_y = property(fget=partial(_getter, 'front', 'y'), fset=partial(_setter, 'front', 'y'))
|
||||
|
||||
top_z = property(fget=partial(_getter, 'front', 'z'), fset=partial(_setter, 'front', 'z'))
|
89
src/sound_lib/main.py
Normal file
89
src/sound_lib/main.py
Normal file
@ -0,0 +1,89 @@
|
||||
from __future__ import absolute_import
|
||||
from future.builtins import object
|
||||
from .external.pybass import *
|
||||
from functools import update_wrapper
|
||||
|
||||
EAX_ENVIRONMENTS = {
|
||||
'generic': EAX_ENVIRONMENT_GENERIC,
|
||||
'padded_cell': EAX_ENVIRONMENT_PADDEDCELL,
|
||||
'room': EAX_ENVIRONMENT_ROOM,
|
||||
'bathroom': EAX_ENVIRONMENT_BATHROOM,
|
||||
'living_room': EAX_ENVIRONMENT_LIVINGROOM,
|
||||
'stone_room': EAX_ENVIRONMENT_STONEROOM,
|
||||
'auditorium': EAX_ENVIRONMENT_AUDITORIUM,
|
||||
'concert_hall': EAX_ENVIRONMENT_CONCERTHALL,
|
||||
'cave': EAX_ENVIRONMENT_CAVE,
|
||||
'arena': EAX_ENVIRONMENT_ARENA,
|
||||
'hanger': EAX_ENVIRONMENT_HANGAR,
|
||||
'carpeted_hallway': EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
'hallway': EAX_ENVIRONMENT_HALLWAY,
|
||||
'stone_corridor': EAX_ENVIRONMENT_STONECORRIDOR,
|
||||
'alley': EAX_ENVIRONMENT_ALLEY,
|
||||
'forest': EAX_ENVIRONMENT_FOREST,
|
||||
'city': EAX_ENVIRONMENT_CITY,
|
||||
'mountains': EAX_ENVIRONMENT_MOUNTAINS,
|
||||
'quarry': EAX_ENVIRONMENT_QUARRY,
|
||||
'plain': EAX_ENVIRONMENT_PLAIN,
|
||||
'parking_lot': EAX_ENVIRONMENT_PARKINGLOT,
|
||||
'sewer_pipe': EAX_ENVIRONMENT_SEWERPIPE,
|
||||
'underwater': EAX_ENVIRONMENT_UNDERWATER,
|
||||
'drugged': EAX_ENVIRONMENT_DRUGGED,
|
||||
'dizzy': EAX_ENVIRONMENT_DIZZY,
|
||||
'psychotic': EAX_ENVIRONMENT_PSYCHOTIC
|
||||
}
|
||||
|
||||
class BassError (Exception):
|
||||
"""Error that is raised when there is a problem with a Bass call."""
|
||||
|
||||
def __init__(self, code, description):
|
||||
self.code = code
|
||||
self.description = description
|
||||
|
||||
def __str__(self):
|
||||
return '%d, %s' % (self.code, self.description)
|
||||
|
||||
def bass_call(function, *args):
|
||||
"""Makes a call to bass and raises an exception if it fails."""
|
||||
res = function(*args)
|
||||
if res == 0 or res == -1:
|
||||
code = BASS_ErrorGetCode()
|
||||
raise BassError(code, get_error_description(code))
|
||||
return res
|
||||
|
||||
def bass_call_0(function, *args):
|
||||
"""Makes a call to bass and raises an exception if it fails. Does not consider 0 an error."""
|
||||
res = function(*args)
|
||||
if res == -1:
|
||||
code = BASS_ErrorGetCode()
|
||||
raise BassError(code, get_error_description(code))
|
||||
return res
|
||||
|
||||
def update_3d_system(func):
|
||||
"""Decorator to automatically update the 3d system after a function call."""
|
||||
def update_3d_system_wrapper(*args, **kwargs):
|
||||
val = func(*args, **kwargs)
|
||||
bass_call( BASS_Apply3D)
|
||||
return val
|
||||
update_wrapper(update_3d_system_wrapper, func)
|
||||
return update_3d_system_wrapper
|
||||
|
||||
class FlagObject(object):
|
||||
"""An object which translates bass flags into human-readable/usable items"""
|
||||
|
||||
def flags_for(self, **flags):
|
||||
res = 0
|
||||
for k, v in flags.items():
|
||||
if v:
|
||||
res |= self.flag_mapping[k]
|
||||
return res
|
||||
|
||||
def setup_flag_mapping(self):
|
||||
self.flag_mapping = {
|
||||
'loop': BASS_SAMPLE_LOOP,
|
||||
'autofree': BASS_STREAM_AUTOFREE,
|
||||
'mono': BASS_SAMPLE_MONO,
|
||||
'software': BASS_SAMPLE_SOFTWARE,
|
||||
'three_d': BASS_SAMPLE_3D,
|
||||
'fx': BASS_SAMPLE_FX,
|
||||
'decode': BASS_STREAM_DECODE,
|
||||
}
|
18
src/sound_lib/music.py
Normal file
18
src/sound_lib/music.py
Normal file
@ -0,0 +1,18 @@
|
||||
from __future__ import absolute_import
|
||||
from .external import pybass
|
||||
from .channel import Channel
|
||||
|
||||
class Music(Channel):
|
||||
|
||||
def __init__(self, mem=False, file=None, offset=0, length=0, flags=0, freq=0):
|
||||
handle = pybass.BASS_MusicLoad(mem, file, offset, length, flags, freq)
|
||||
super(Music, self).__init__(handle)
|
||||
self.add_attributes_to_mapping(
|
||||
music_amplify=pybass.BASS_ATTRIB_MUSIC_AMPLIFY,
|
||||
music_bpm = pybass.BASS_ATTRIB_MUSIC_BPM,
|
||||
music_pansep=pybass.BASS_ATTRIB_MUSIC_PANSEP,
|
||||
music_speed=pybass.BASS_ATTRIB_MUSIC_SPEED,
|
||||
music_vol_chan=pybass.BASS_ATTRIB_MUSIC_VOL_CHAN,
|
||||
music_vol_global=pybass.BASS_ATTRIB_MUSIC_VOL_GLOBAL,
|
||||
music_vol_inst=pybass.BASS_ATTRIB_MUSIC_VOL_INST,
|
||||
)
|
190
src/sound_lib/output.py
Normal file
190
src/sound_lib/output.py
Normal file
@ -0,0 +1,190 @@
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
from future.builtins import object
|
||||
from functools import partial
|
||||
import platform
|
||||
from ctypes import c_char_p, c_float, pointer, string_at
|
||||
from sound_lib.external.pybass import *
|
||||
from . import config
|
||||
from .main import bass_call, bass_call_0, EAX_ENVIRONMENTS, update_3d_system
|
||||
|
||||
_getter = lambda func, key, obj: func(obj)[key]
|
||||
_setter = lambda func, kwarg, obj, val: func(obj, **{kwarg: val})
|
||||
|
||||
class Output (object):
|
||||
|
||||
def __init__(self, device=-1, frequency=44100, flags=0, window=0, clsid=None):
|
||||
try:
|
||||
self.use_default_device()
|
||||
except:
|
||||
pass
|
||||
self._device = device
|
||||
self.frequency = frequency
|
||||
self.flags = flags
|
||||
self.window = window
|
||||
self.clsid = clsid
|
||||
self.init_device(device=device, frequency=frequency, flags=flags, window=window, clsid=clsid)
|
||||
self.config = config.BassConfig()
|
||||
self.proxy = None
|
||||
|
||||
def init_device(self, device=None, frequency=None, flags=None, window=None, clsid=None):
|
||||
if device is None:
|
||||
device = self._device
|
||||
self._device = device
|
||||
if frequency is None:
|
||||
frequency = self.frequency
|
||||
self.frequency = frequency
|
||||
if flags is None:
|
||||
flags = self.flags
|
||||
self.flags = flags
|
||||
if window is None:
|
||||
window = self.window
|
||||
self.window = window
|
||||
if clsid is None:
|
||||
clsid = self.clsid
|
||||
self.clsid = clsid
|
||||
if platform.system() == 'Linux' and device == -1: #Bass wants default device set to 1 on linux
|
||||
device = 1
|
||||
bass_call(BASS_Init, device, frequency, flags, window, clsid)
|
||||
|
||||
def start(self):
|
||||
return bass_call(BASS_Start)
|
||||
|
||||
def pause(self):
|
||||
return bass_call(BASS_Pause)
|
||||
|
||||
def stop(self):
|
||||
return bass_call(BASS_Stop)
|
||||
|
||||
def get_device(self):
|
||||
return bass_call_0(BASS_GetDevice)
|
||||
|
||||
def set_device(self, device):
|
||||
if device == self._device:
|
||||
return
|
||||
self.free()
|
||||
self.init_device(device=device)
|
||||
return bass_call(BASS_SetDevice, device)
|
||||
|
||||
device = property(fget=get_device, fset=set_device)
|
||||
|
||||
def get_volume (self):
|
||||
volume = BASS_GetConfig(BASS_CONFIG_GVOL_STREAM)
|
||||
if volume:
|
||||
volume = volume / 100.0
|
||||
return volume
|
||||
|
||||
def set_volume (self, volume):
|
||||
#Pass in a float 0.0 to 100.0 and watch the volume magically change
|
||||
return bass_call(BASS_SetConfig, BASS_CONFIG_GVOL_STREAM, int(round(volume*100, 2)))
|
||||
|
||||
volume = property(get_volume, set_volume)
|
||||
|
||||
@staticmethod
|
||||
def free():
|
||||
return bass_call(BASS_Free)
|
||||
|
||||
def get_proxy(self):
|
||||
ptr = bass_call(BASS_GetConfigPtr, BASS_CONFIG_NET_PROXY)
|
||||
return string_at(ptr)
|
||||
|
||||
def set_proxy(self, proxy):
|
||||
self.proxy = c_char_p(proxy)
|
||||
return bass_call(BASS_SetConfigPtr, BASS_CONFIG_NET_PROXY, self.proxy)
|
||||
|
||||
def use_default_device(self, use=True):
|
||||
return bass_call(BASS_SetConfig, BASS_CONFIG_DEV_DEFAULT, use)
|
||||
|
||||
@staticmethod
|
||||
def get_device_names():
|
||||
"""Convenience method that returns a list of device names that are considered
|
||||
valid by bass.
|
||||
|
||||
Parameters: none.
|
||||
returns: list of devices, 0-indexed.
|
||||
"""
|
||||
result = [] # empty list to start.
|
||||
info = BASS_DEVICEINFO()
|
||||
count = 1
|
||||
while BASS_GetDeviceInfo(count, ctypes.byref(info)):
|
||||
if info.flags & BASS_DEVICE_ENABLED:
|
||||
retrieved = info.name
|
||||
if platform.system() == 'Windows':
|
||||
retrieved = retrieved.decode('mbcs')
|
||||
retrieved = retrieved.replace('(', '').replace(')', '').strip()
|
||||
result.append(retrieved)
|
||||
count += 1
|
||||
return result
|
||||
|
||||
def find_device_by_name(self, name):
|
||||
return self.get_device_names().index(name) + 1
|
||||
|
||||
def find_default_device(self):
|
||||
try:
|
||||
return self.get_device_names().index('Default')+1
|
||||
except:
|
||||
return -1
|
||||
|
||||
def find_user_provided_device(self, device_name):
|
||||
try:
|
||||
return self.find_device_by_name(device_name)
|
||||
except ValueError:
|
||||
return self.find_default_device()
|
||||
|
||||
class ThreeDOutput(Output):
|
||||
|
||||
def __init__(self, flags=BASS_DEVICE_3D, *args, **kwargs):
|
||||
super(ThreeDOutput, self).__init__(flags=flags, *args, **kwargs)
|
||||
|
||||
def get_3d_factors(self):
|
||||
res = {
|
||||
'distance_factor': c_float(),
|
||||
'rolloff': c_float(),
|
||||
'doppler_factor': c_float()
|
||||
}
|
||||
bass_call(BASS_Get3DFactors, pointer(res['distance_factor']), pointer(res['rolloff']), pointer(res['doppler_factor']))
|
||||
return {k: res[k].value for k in res}
|
||||
|
||||
@update_3d_system
|
||||
def set_3d_factors(self, distance_factor=-1, rolloff=-1, doppler_factor=-1):
|
||||
conversions = {
|
||||
'meters': 1.0,
|
||||
'yards': 0.9144,
|
||||
'feet': 0.3048
|
||||
}
|
||||
if distance_factor in conversions:
|
||||
distance_factor = conversions[distance_factor]
|
||||
return bass_call(BASS_Set3DFactors, distance_factor, rolloff, doppler_factor)
|
||||
|
||||
distance_factor = property(fget=partial(_getter, get_3d_factors, 'distance_factor'), fset=partial(_setter, set_3d_factors, 'distance_factor'))
|
||||
|
||||
rolloff = property(fget=partial(_getter, get_3d_factors, 'rolloff'), fset=partial(_setter, set_3d_factors, 'rolloff'))
|
||||
|
||||
doppler_factor = property(fget=partial(_getter, get_3d_factors, 'doppler_factor'), fset=partial(_setter, set_3d_factors, 'doppler_factor'))
|
||||
|
||||
def set_eax_parameters(self, environment=None, volume=None, decay=None, damp=None):
|
||||
def convert_arg(arg):
|
||||
if arg is None:
|
||||
arg = -1
|
||||
return arg
|
||||
environment = convert_arg(environment)
|
||||
if isinstance(environment, str) and environment in EAX_ENVIRONMENTS:
|
||||
environment = EAX_ENVIRONMENTS[environment]
|
||||
volume = convert_arg(volume)
|
||||
decay = convert_arg(decay)
|
||||
damp = convert_arg(damp)
|
||||
bass_call(BASS_SetEAXParameters, environment, volume, decay, damp)
|
||||
|
||||
def get_3d_algorithm(self):
|
||||
return BASS_GetConfig(BASS_CONFIG_3DALGORITHM)
|
||||
|
||||
def set_3d_algorithm(self, algo):
|
||||
replacements = {
|
||||
'default': BASS_3DALG_DEFAULT,
|
||||
'off': BASS_3DALG_OFF,
|
||||
'full': BASS_3DALG_FULL,
|
||||
'light': BASS_3DALG_LIGHT,
|
||||
}
|
||||
if algo in replacements:
|
||||
algo = replacements[algo]
|
||||
return BASS_SetConfig(BASS_CONFIG_3DALGORITHM, algo)
|
49
src/sound_lib/recording.py
Normal file
49
src/sound_lib/recording.py
Normal file
@ -0,0 +1,49 @@
|
||||
from __future__ import absolute_import
|
||||
from .channel import Channel
|
||||
from .external.pybass import *
|
||||
from ctypes import string_at
|
||||
import wave
|
||||
from .main import bass_call, bass_call_0
|
||||
|
||||
class Recording(Channel):
|
||||
|
||||
def __init__(self, frequency=44100, channels=2, flags=BASS_RECORD_PAUSE, proc=None, user=None):
|
||||
if not proc:
|
||||
proc = lambda: True
|
||||
self.callback = RECORDPROC(proc)
|
||||
self._frequency = frequency
|
||||
self._channels = channels
|
||||
self._flags = flags
|
||||
handle = bass_call(BASS_RecordStart, frequency, channels, flags, self.callback, user)
|
||||
super(Recording, self).__init__(handle)
|
||||
|
||||
def free(self):
|
||||
pass
|
||||
|
||||
|
||||
class WaveRecording(Recording):
|
||||
|
||||
def __init__(self, filename=None, proc=None, *args, **kwargs):
|
||||
callback = proc or self.recording_callback
|
||||
super(WaveRecording, self).__init__(proc=callback, *args, **kwargs)
|
||||
self.filename = filename
|
||||
|
||||
def recording_callback(self, handle, buffer, length, user):
|
||||
buf = string_at(buffer, length)
|
||||
self.file.writeframes(buf)
|
||||
return True
|
||||
|
||||
def setup_file(self):
|
||||
self.file = wave.open(self.filename, 'w')
|
||||
self.file.setnchannels(self._channels)
|
||||
self.file.setsampwidth(2)
|
||||
self.file.setframerate(self._frequency)
|
||||
|
||||
def play(self, *args, **kwargs):
|
||||
if not self.is_playing:
|
||||
self.setup_file()
|
||||
super(WaveRecording, self).play(*args, **kwargs)
|
||||
|
||||
def stop(self, *args, **kwargs):
|
||||
super(WaveRecording, self).stop(*args, **kwargs)
|
||||
self.file.close()
|
61
src/sound_lib/stream.py
Normal file
61
src/sound_lib/stream.py
Normal file
@ -0,0 +1,61 @@
|
||||
from __future__ import absolute_import
|
||||
import platform
|
||||
import sys
|
||||
from .channel import Channel
|
||||
from .main import bass_call, bass_call_0
|
||||
from .external.pybass import *
|
||||
|
||||
convert_to_unicode = str
|
||||
|
||||
class BaseStream(Channel):
|
||||
|
||||
def _callback(*args):
|
||||
#Stub it out as otherwise it'll crash, hard. Used for stubbing download procs
|
||||
return 0
|
||||
|
||||
def free(self):
|
||||
return bass_call(BASS_StreamFree, self.handle)
|
||||
|
||||
def get_file_position(self, mode):
|
||||
return bass_call_0(BASS_StreamGetFilePosition, self.handle, mode)
|
||||
|
||||
class Stream(BaseStream):
|
||||
|
||||
def __init__(self, freq=44100, chans=2, flags=0, proc=None, user=None, three_d=False, autofree=False, decode=False):
|
||||
self.proc = STREAMPROC(proc)
|
||||
self.setup_flag_mapping()
|
||||
flags = flags | self.flags_for(three_d=three_d, autofree=autofree, decode=decode)
|
||||
handle = bass_call(BASS_StreamCreate, freq, chans, flags, self.proc, user)
|
||||
super(Stream, self).__init__(handle)
|
||||
|
||||
class FileStream(BaseStream):
|
||||
|
||||
def __init__(self, mem=False, file=None, offset=0, length=0, flags=0, three_d=False, mono=False, autofree=False, decode=False, unicode=True):
|
||||
"""Creates a sample stream from an MP3, MP2, MP1, OGG, WAV, AIFF or plugin supported file."""
|
||||
if platform.system() == 'Darwin' or platform.system() == "Linux":
|
||||
unicode = False
|
||||
file = file.encode(sys.getfilesystemencoding())
|
||||
self.setup_flag_mapping()
|
||||
flags = flags | self.flags_for(three_d=three_d, autofree=autofree, mono=mono, decode=decode, unicode=unicode)
|
||||
if unicode and isinstance(file, str):
|
||||
file = convert_to_unicode(file)
|
||||
self.file = file
|
||||
handle = bass_call(BASS_StreamCreateFile, mem, file, offset, length, flags)
|
||||
super(FileStream, self).__init__(handle)
|
||||
|
||||
def setup_flag_mapping(self):
|
||||
super(FileStream, self).setup_flag_mapping()
|
||||
self.flag_mapping.update({
|
||||
'unicode': BASS_UNICODE
|
||||
})
|
||||
|
||||
class URLStream(BaseStream):
|
||||
|
||||
def __init__(self, url="", offset=0, flags=0, downloadproc=None, user=None, three_d=False, autofree=False, decode=False):
|
||||
self._downloadproc = downloadproc or self._callback #we *must hold on to this
|
||||
self.downloadproc = DOWNLOADPROC(self._downloadproc)
|
||||
self.url = url
|
||||
self.setup_flag_mapping()
|
||||
flags = flags | self.flags_for(three_d=three_d, autofree=autofree, decode=decode)
|
||||
handle = bass_call(BASS_StreamCreateURL, url, offset, flags, self.downloadproc, user)
|
||||
super(URLStream, self).__init__(handle)
|
@ -55,6 +55,15 @@ class audioTab(homeTab):
|
||||
self.list.set_size()
|
||||
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
|
||||
|
||||
def create_post_buttons(self):
|
||||
self.post = wx.Button(self, -1, _(u"Post"))
|
||||
self.play = wx.Button(self, -1, _(u"Play"))
|
||||
self.play_all = wx.Button(self, -1, _(u"Play All"))
|
||||
self.postBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.postBox.Add(self.post, 0, wx.ALL, 5)
|
||||
self.postBox.Add(self.play, 0, wx.ALL, 5)
|
||||
self.postBox.Add(self.play_all, 0, wx.ALL, 5)
|
||||
|
||||
class notificationsTab(homeTab):
|
||||
def __init__(self, parent):
|
||||
super(notificationsTab, self).__init__(parent=parent)
|
||||
|
Loading…
Reference in New Issue
Block a user