2023-04-02 03:57:11 +00:00
|
|
|
import os
|
|
|
|
import pathlib
|
|
|
|
|
|
|
|
from fastapi import FastAPI
|
|
|
|
from fastapi.responses import FileResponse
|
|
|
|
from pydantic import BaseModel
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from AccelBrainBeat.brainbeat.binaural_beat import BinauralBeat
|
|
|
|
import pydub
|
|
|
|
import random
|
|
|
|
|
2023-04-02 16:15:59 +00:00
|
|
|
from animate_fractal import animategif
|
2023-04-02 03:57:11 +00:00
|
|
|
from blend_av import blend_av
|
|
|
|
|
|
|
|
app = FastAPI()
|
|
|
|
|
|
|
|
|
|
|
|
class App(BaseModel):
|
|
|
|
app: str
|
|
|
|
|
|
|
|
|
|
|
|
class AudioProperties(BaseModel):
|
|
|
|
"""
|
|
|
|
Audio properties
|
|
|
|
"""
|
|
|
|
main_frequency: int
|
|
|
|
lag_frequency: int
|
|
|
|
volume: float
|
|
|
|
breath_pattern_in: int
|
|
|
|
breath_pattern_out: int
|
|
|
|
bell_sound: str
|
|
|
|
|
|
|
|
|
|
|
|
class VideoProperties(BaseModel):
|
|
|
|
"""
|
|
|
|
Video properties
|
|
|
|
"""
|
|
|
|
main_frequency: int
|
|
|
|
breath_pattern_in: int
|
|
|
|
breath_pattern_out: int
|
2023-04-02 16:15:59 +00:00
|
|
|
color_scheme = str
|
2023-04-02 03:57:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
class AvProperties(BaseModel):
|
|
|
|
"""
|
|
|
|
Audio and video properties
|
|
|
|
"""
|
|
|
|
main_frequency: int
|
|
|
|
lag_frequency: int
|
|
|
|
volume: float
|
|
|
|
breath_pattern_in: int
|
|
|
|
breath_pattern_out: int
|
|
|
|
bell_sound: str
|
|
|
|
color_palette = str
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/")
|
|
|
|
async def get_root():
|
|
|
|
appresponse = App(app='breathaudio')
|
|
|
|
return appresponse
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/generate_audio")
|
|
|
|
async def get_generate_audio(audio_properties: AudioProperties):
|
|
|
|
"""
|
|
|
|
Generate audio
|
|
|
|
:param audio_properties:
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
tmp_dir = pathlib.Path("tmp_sound")
|
|
|
|
tmp_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Remove existing files in tmp_dir
|
|
|
|
for filename in os.listdir(tmp_dir):
|
2023-04-02 16:15:59 +00:00
|
|
|
os.remove(tmp_dir / str(filename))
|
2023-04-02 03:57:11 +00:00
|
|
|
bell_dir = pathlib.Path("bell")
|
|
|
|
filename_prefix = ''.join([random.choice('0123456789ABCDEF') for i in range(32)])
|
|
|
|
filename = f"{filename_prefix}.wav"
|
|
|
|
# Generate binaural beat
|
|
|
|
b = BinauralBeat()
|
|
|
|
b.save_beat(output_file_name=str(tmp_dir / "binaural_beat.wav"),
|
|
|
|
frequencys=(audio_properties.main_frequency,
|
|
|
|
audio_properties.lag_frequency),
|
2023-04-02 16:15:59 +00:00
|
|
|
play_time=(audio_properties.breath_pattern_in + audio_properties.breath_pattern_out) * 2,
|
2023-04-02 03:57:11 +00:00
|
|
|
volume=audio_properties.volume
|
|
|
|
)
|
|
|
|
pydub_background = pydub.AudioSegment.from_wav(tmp_dir / "binaural_beat.wav")
|
2023-04-02 16:15:59 +00:00
|
|
|
bell_file = ""
|
|
|
|
if audio_properties.bell_sound == "Cloche":
|
|
|
|
bell_file = "339810__inspectorj__hand-bells-a-single-mod.wav"
|
|
|
|
skip_bell = False
|
|
|
|
elif audio_properties.bell_sound == "Bol tibétain":
|
|
|
|
bell_file = "417116__dersinnsspace__tibetan-bowl_right-hit-mod.wav"
|
|
|
|
skip_bell = False
|
|
|
|
else:
|
|
|
|
skip_bell = True
|
|
|
|
if skip_bell:
|
|
|
|
pydub_mix = pydub_background
|
|
|
|
else:
|
|
|
|
pydub_bell = pydub.AudioSegment.from_wav(bell_dir / bell_file)
|
|
|
|
pydub_mix = pydub_background. \
|
|
|
|
overlay(pydub_bell, position=0). \
|
|
|
|
overlay(pydub_bell, position=audio_properties.breath_pattern_in * 1000). \
|
|
|
|
overlay(pydub_bell,
|
|
|
|
position=(audio_properties.breath_pattern_in + audio_properties.breath_pattern_out) * 1000). \
|
|
|
|
overlay(pydub_bell,
|
|
|
|
position=(audio_properties.breath_pattern_in * 2 + audio_properties.breath_pattern_out) * 1000)
|
2023-04-02 03:57:11 +00:00
|
|
|
pydub_mix.export(tmp_dir / filename, format="wav")
|
2023-04-02 16:15:59 +00:00
|
|
|
return FileResponse(tmp_dir / filename)
|
2023-04-02 03:57:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
@app.get("/generate_video")
|
|
|
|
async def get_generate_video(video_properties: VideoProperties):
|
|
|
|
"""
|
|
|
|
Generate video
|
|
|
|
:param video_properties:
|
|
|
|
:return:
|
|
|
|
"""
|
2023-04-02 16:15:59 +00:00
|
|
|
tmp_dir = pathlib.Path("tmp_video")
|
|
|
|
tmp_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Remove existing files in tmp_dir
|
|
|
|
for filename in os.listdir(tmp_dir):
|
|
|
|
os.remove(tmp_dir / str(filename))
|
|
|
|
anim = animategif()
|
|
|
|
filename_prefix = ''.join([random.choice('0123456789ABCDEF') for i in range(32)])
|
|
|
|
filename = f"{filename_prefix}.gif"
|
|
|
|
anim.save(str(tmp_dir / filename), writer='imagemagick')
|
|
|
|
return FileResponse(str(tmp_dir / filename))
|
2023-04-02 03:57:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
@app.get("/generate_av")
|
|
|
|
async def get_generate_av(av_properties: AvProperties):
|
|
|
|
"""
|
|
|
|
Generate audio and video using blend_av
|
|
|
|
:param av_properties:
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
|
|
|
|
a = AudioProperties()
|
|
|
|
a.main_frequency = av_properties.main_frequency
|
|
|
|
a.breath_pattern_in = av_properties.breath_pattern_in
|
|
|
|
a.breath_pattern_out = av_properties.breath_pattern_out
|
|
|
|
a.bell_sound = av_properties.bell_sound
|
|
|
|
audio = get_generate_audio(a)
|
|
|
|
|
|
|
|
v = VideoProperties()
|
|
|
|
v.main_frequency = av_properties.main_frequency
|
|
|
|
v.breath_pattern_in = av_properties.breath_pattern_in
|
|
|
|
v.breath_pattern_out = av_properties.breath_pattern_out
|
|
|
|
v.color_palette = av_properties.color_palette
|
|
|
|
video = get_generate_video(v)
|
|
|
|
|
|
|
|
av = blend_av(audio, video)
|
|
|
|
return FileResponse(av)
|
|
|
|
|
|
|
|
|
|
|
|
client = TestClient(app)
|
|
|
|
|
|
|
|
|
|
|
|
def test_getroot():
|
|
|
|
response = client.get("/")
|
|
|
|
assert response.status_code == 200
|