Skip to content

Commit

Permalink
Setup argument and return types for BASS functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
MahmoudAtef999 committed Dec 25, 2024
1 parent 64b690c commit 1aeb640
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
20 changes: 18 additions & 2 deletions utils/audio_player/bass_init.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import os
import ctypes
from ctypes import c_int, c_longlong, c_void_p, c_uint
from ctypes import c_int, c_longlong, c_void_p, c_uint, c_double
from enum import IntFlag
from exceptions.audio_pplayer import PlaybackInitializationError


class BassFlag(IntFlag):
AUTO_FREE = 0x40000 # Automatically free the stream when it stops/ends
STREAM_BLOCK = 0x100000 # Download/play internet file stream in small blocks
MUSIC_NOSAMPLE = 0x100000
STREAM_STATUS = 0x800000
STREAM_RESTRATE = 0x80000


class BassInitializer:
def __init__(self, bass_library_path: str = "bass.dll"):
"""Initialize the BassInitializer object without loading the library or initializing BASS."""
self.bass_library_path = os.path.abspath(bass_library_path)
self.bass = None
self.setup()
Expand All @@ -26,8 +28,22 @@ def setup(self):
self.bass = ctypes.CDLL(self.bass_library_path)

# Setup argument and return types for BASS functions
self.bass.BASS_Init.argtypes = [c_int, c_uint, c_uint, c_void_p, c_void_p]
self.bass.BASS_Init.restype = c_int
self.bass.BASS_StreamCreateFile.argtypes = [c_int, c_void_p, c_longlong, c_longlong, c_uint]
self.bass.BASS_StreamCreateFile.restype = c_int
self.bass.BASS_StreamCreateURL.argtypes = [c_void_p, c_int, c_uint, c_void_p, c_void_p]
self.bass.BASS_StreamCreateURL.restype = c_int
self.bass.BASS_ChannelBytes2Seconds.argtypes = [c_int, c_longlong]
self.bass.BASS_ChannelBytes2Seconds.restype = c_double
self.bass.BASS_ChannelSeconds2Bytes.argtypes = [c_int, c_double]
self.bass.BASS_ChannelSeconds2Bytes.restype = c_longlong
self.bass.BASS_ChannelSetPosition.argtypes = [c_int, c_longlong, c_uint]
self.bass.BASS_ChannelSetPosition.restype = c_int
self.bass.BASS_ChannelGetLength.argtypes = [c_int, c_uint]
self.bass.BASS_ChannelGetLength.restype = c_longlong
self.bass.BASS_ChannelGetPosition.argtypes = [c_int, c_uint]
self.bass.BASS_ChannelGetPosition.restype = c_longlong
self.bass.BASS_ErrorGetCode.restype = c_int

def initialize(self):
Expand Down
17 changes: 5 additions & 12 deletions utils/audio_player/bass_player.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import os
import time
import ctypes
from ctypes import c_int, c_int64, c_long, c_uint, c_longlong, c_void_p
func_type = ctypes.WINFUNCTYPE
QWORD = ctypes.c_int64

from typing import List, Optional
from urllib.parse import urlparse
from .status import PlaybackStatus
Expand All @@ -25,9 +21,6 @@ def __init__(self, volume: float, flag: int = BassFlag.AUTO_FREE) -> None:
self.volume = volume
self.supported_extensions = ('.wav', '.mp3', '.ogg')
self.flag = flag
self.BASS_ChannelBytes2Seconds = func_type(ctypes.c_double, ctypes.c_ulong, QWORD)(('BASS_ChannelBytes2Seconds', bass))
self.BASS_ChannelSeconds2Bytes = func_type(QWORD, ctypes.c_ulong, ctypes.c_double)(('BASS_ChannelSeconds2Bytes', bass))
self.BASS_ChannelSetPosition = func_type(ctypes.c_bool, ctypes.c_ulong, QWORD, ctypes.c_ulong)(('BASS_ChannelSetPosition', bass))
AudioPlayer.instances.append(self)

def load_audio(self, source: str, attempts: Optional[int] = 3) -> None:
Expand Down Expand Up @@ -106,10 +99,10 @@ def set_position(self, new_seconds: float) -> None:
if self.current_channel:
new_seconds = max(0.0, new_seconds)

duration = self.BASS_ChannelBytes2Seconds(self.current_channel, bass.BASS_ChannelGetLength( self.current_channel, 0))
duration = bass.BASS_ChannelBytes2Seconds(self.current_channel, bass.BASS_ChannelGetLength( self.current_channel, 0))
new_seconds = min(new_seconds, duration-1)
new_position = self.BASS_ChannelSeconds2Bytes(self.current_channel, new_seconds)
self.BASS_ChannelSetPosition(self.current_channel, new_position, 0)
new_position = bass.BASS_ChannelSeconds2Bytes(self.current_channel, new_seconds)
bass.BASS_ChannelSetPosition(self.current_channel, new_position, 0)

def forward(self, seconds: int = 5) -> None:
"""Forwards the audio playback by the specified number of seconds."""
Expand All @@ -119,7 +112,7 @@ def forward(self, seconds: int = 5) -> None:
print("Error getting current position.")
return

current_seconds = self.BASS_ChannelBytes2Seconds(self.current_channel, current_position)
current_seconds = bass.BASS_ChannelBytes2Seconds(self.current_channel, current_position)
new_seconds = round(current_seconds + seconds)
self.set_position(new_seconds)

Expand All @@ -131,7 +124,7 @@ def rewind(self, seconds: int = 5) -> None:
print("Error getting current position.")
return

current_seconds = self.BASS_ChannelBytes2Seconds(self.current_channel, current_position)
current_seconds = bass.BASS_ChannelBytes2Seconds(self.current_channel, current_position)
new_seconds = current_seconds - seconds
self.set_position(new_seconds)

Expand Down

0 comments on commit 1aeb640

Please sign in to comment.