Skip to content

Commit 8e6d396

Browse files
authored
Create ByteBeat.py
1 parent 841a633 commit 8e6d396

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

ByteBeat.py

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import ctypes
2+
from ctypes import byref, create_string_buffer, c_int, c_long, c_byte, POINTER, sizeof
3+
from win32api import Sleep
4+
from numpy import sin, tan, cos, sqrt
5+
from math import floor, ceil
6+
from numpy import log as ln
7+
from functools import partial
8+
9+
class Infix(object):
10+
def __init__(self, func): self.func = func
11+
def __or__(self, other): return self.func(other)
12+
def __ror__(self, other): return Infix(partial(self.func, other))
13+
def __call__(self, v1, v2): return self.func(v1, v2)
14+
LPSTR,BYTE,WORD,UINT,DWORD,HANDLE=ctypes.c_char_p,ctypes.c_byte,ctypes.c_ushort,ctypes.c_uint,ctypes.c_ulong,ctypes.c_void_p
15+
HWAVEOUT,LPHWAVEOUT = HANDLE,POINTER(HWAVEOUT)
16+
winmm = ctypes.windll.Winmm
17+
waveOutOpen,waveOutPrepareHeader,waveOutWrite,waveOutUnprepareHeader,waveOutClose=winmm.waveOutOpen,winmm.waveOutPrepareHeader,winmm.waveOutWrite,winmm.waveOutUnprepareHeader,winmm.waveOutClose
18+
WAVE_FORMAT_PCM,WAVE_MAPPER,CALLBACK_NULL=1,-1,0
19+
20+
class WAVEFORMATEX(ctypes.Structure):
21+
_fields_ = [
22+
("wFormatTag", WORD),
23+
("nChannels", WORD),
24+
("nSamplesPerSec", DWORD),
25+
("nAvgBytesPerSec", DWORD),
26+
("nBlockAlign", WORD),
27+
("wBitsPerSample", WORD),
28+
("cbSize", WORD)
29+
]
30+
LPWAVEFORMATEX = POINTER(WAVEFORMATEX)
31+
class WAVEHDR(ctypes.Structure):
32+
pass
33+
LPWAVEHDR = POINTER(WAVEHDR)
34+
WAVEHDR._fields_ = [
35+
("lpData", LPSTR),
36+
("dwBufferLength", DWORD),
37+
("dwBytesRecorded", DWORD),
38+
("dwUser", DWORD),
39+
("dwFlags", DWORD),
40+
("dwLoops", DWORD),
41+
("lpNext", LPWAVEHDR),
42+
("reserved", DWORD)
43+
]
44+
LPWAVEHDR = POINTER(WAVEHDR)
45+
division_key_fix=Infix(lambda x,y: x/y if y else 0)
46+
operand_key_fix=Infix(lambda x,y: int(x)|int(y))
47+
charcodeat_key_fix=Infix(lambda s,y: ord(s[y]))
48+
operand_gtgt_key_fix=Infix(lambda x,y: int(x)>>int(y))
49+
operand_ltlt_key_fix=Infix(lambda x, y: int(x)<<int(y))
50+
51+
class ByteBeat:
52+
def GenerateBuffer(EQUATION, SECONDS_PLAYING, AMOUNT_KILOHERTZ=8000):
53+
'''
54+
> GenerateBuffer function
55+
- Generates buffering data playable via the PlayFromBuffer function
56+
@ EQUATION argument: Mathematical ByteBeat input eg. 't%0.86*t'
57+
@ EQUATION type: str
58+
@ SECONDS_PLAYING argument: The length of the ByteBeat, in seconds
59+
@ SECONDS_PLAYING type: int
60+
@ AMOUNT_KILOHERTZ argument: The amount of kilohertz (kHz) the ByteBeat will use.
61+
@ AMOUNT_KILOHERTZ type: int
62+
'''
63+
EQUATION = EQUATION.replace('^','**').replace('random()','__import__("random").random()').replace('|','|operand_key_fix|').replace('/','|division_key_fix|').replace('?',' if ').replace(':',' else ').replace('.charCodeAt',' |charcodeat_key_fix| ').replace('>>',' |operand_gtgt_key_fix| ').replace('<<',' |operand_ltlt_key_fix| ')
64+
hWaveOut = HWAVEOUT(0)
65+
wfx = WAVEFORMATEX(WAVE_FORMAT_PCM, 1, AMOUNT_KILOHERTZ, AMOUNT_KILOHERTZ, 1, 8,0)
66+
waveOutOpen(byref(hWaveOut), WAVE_MAPPER, LPWAVEFORMATEX(wfx), 0, 0, CALLBACK_NULL)
67+
buffer = create_string_buffer(int(AMOUNT_KILOHERTZ) * SECONDS_PLAYING)
68+
for t in range(0, int(AMOUNT_KILOHERTZ) * SECONDS_PLAYING):buffer.value += c_byte(int(eval(EQUATION)))
69+
return buffer.raw
70+
71+
def Play(EQUATION, SECONDS_PLAYING, AMOUNT_KILOHERTZ, ASYNC_SLEEP = False):
72+
'''
73+
> Play function
74+
- Generates buffering data and plays the result when it finished.
75+
@ EQUATION argument: Mathematical ByteBeat input eg. 't%0.86*t'
76+
@ EQUATION type: str
77+
@ SECONDS_PLAYING argument: The length of the ByteBeat, in seconds
78+
@ SECONDS_PLAYING type: int
79+
@ AMOUNT_KILOHERTZ argument: The amount of kilohertz (kHz) the ByteBeat will use.
80+
@ AMOUNT_KILOHERTZ type: int
81+
@ ASYNC_SLEEP argument: Wait until the sound playing has finished or not.
82+
@ ASYNC_SLEEP type: bool
83+
'''
84+
EQUATION = EQUATION.replace('^','**').replace('random()','__import__("random").random()').replace('|','|operand_key_fix|').replace('/','|division_key_fix|').replace('?',' if ').replace(':',' else ').replace('.charCodeAt',' |charcodeat_key_fix| ').replace('>>',' |operand_gtgt_key_fix| ').replace('<<',' |operand_ltlt_key_fix| ')
85+
hWaveOut = HWAVEOUT(0)
86+
wfx = WAVEFORMATEX(WAVE_FORMAT_PCM, 1, AMOUNT_KILOHERTZ, AMOUNT_KILOHERTZ, 1, 8,0)
87+
winmm.waveOutOpen.argtypes = (LPHWAVEOUT, UINT, LPWAVEFORMATEX, DWORD, DWORD, DWORD)
88+
waveOutOpen(byref(hWaveOut), WAVE_MAPPER, LPWAVEFORMATEX(wfx), 0, 0, CALLBACK_NULL)
89+
buffer = create_string_buffer(int(AMOUNT_KILOHERTZ) * SECONDS_PLAYING)
90+
for t in range(0, int(AMOUNT_KILOHERTZ) * SECONDS_PLAYING):buffer.value += c_byte(int(eval(EQUATION)))
91+
buffer = buffer.raw
92+
wHeader = WAVEHDR(buffer, len(buffer), 0, 0, 0, 0)
93+
waveOutPrepareHeader(hWaveOut, byref(wHeader), sizeof(WAVEHDR))
94+
waveOutWrite(hWaveOut, byref(wHeader), sizeof(WAVEHDR))
95+
waveOutUnprepareHeader(hWaveOut, byref(wHeader), sizeof(WAVEHDR))
96+
waveOutClose(hWaveOut)
97+
if ASYNC_SLEEP: Sleep(SECONDS_PLAYING*1000)
98+
return True
99+
def PlayFromBuffer(buffer, SECONDS_PLAYING, AMOUNT_KILOHERTZ, ASYNC_SLEEP=False):
100+
'''
101+
> PlayFromBuffer function
102+
- Plays buffering data generatable using the GenerateBuffer function
103+
@ buffer argument: String buffering data
104+
@ buffer type: str
105+
@ SECONDS_PLAYING argument: The length of the ByteBeat, in seconds
106+
@ SECONDS_PLAYING type: int
107+
@ AMOUNT_KILOHERTZ argument: The amount of kilohertz (kHz) the ByteBeat will use
108+
@ AMOUNT_KILOHERTZ type: int
109+
@ ASYNC_SLEEP argument: Wait until the sound playing has finished or not
110+
@ ASYNC_SLEEP type: bool
111+
'''
112+
hWaveOut = HWAVEOUT(0)
113+
wfx = WAVEFORMATEX(WAVE_FORMAT_PCM, 1, AMOUNT_KILOHERTZ, AMOUNT_KILOHERTZ, 1, 8,0)
114+
waveOutOpen(byref(hWaveOut), WAVE_MAPPER, LPWAVEFORMATEX(wfx), 0, 0, CALLBACK_NULL)
115+
wHeader = WAVEHDR(buffer, len(buffer), 0, 0, 0, 0)
116+
waveOutPrepareHeader(hWaveOut, byref(wHeader), sizeof(WAVEHDR))
117+
waveOutWrite(hWaveOut, byref(wHeader), sizeof(WAVEHDR))
118+
waveOutUnprepareHeader(hWaveOut, byref(wHeader), sizeof(WAVEHDR))
119+
waveOutClose(hWaveOut)
120+
if ASYNC_SLEEP: Sleep(SECONDS_PLAYING*1000)
121+
return True

0 commit comments

Comments
 (0)