choix de cloche et vidéo gif fonctionnelle
This commit is contained in:
parent
eae8367550
commit
55340872df
6 changed files with 97 additions and 15 deletions
|
@ -19,8 +19,5 @@ RUN pip install -r requirements.txt
|
|||
COPY *.py ./
|
||||
RUN python install.py
|
||||
|
||||
# Copy the app's code
|
||||
COPY main.py .
|
||||
|
||||
# Run the application
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
39
animate_fractal.py
Normal file
39
animate_fractal.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import animation
|
||||
|
||||
from mandelbrot import mandelbrot
|
||||
|
||||
|
||||
def animategif():
|
||||
x_start, y_start = -2, -1.5 # an interesting region starts here
|
||||
width, height = 3, 3 # for 3 units up and right
|
||||
density_per_unit = 100 # how many pixels per unit
|
||||
|
||||
# real and imaginary axis
|
||||
re = np.linspace(x_start, x_start + width, width * density_per_unit)
|
||||
im = np.linspace(y_start, y_start + height, height * density_per_unit)
|
||||
|
||||
fig = plt.figure(figsize=(5, 5)) # instantiate a figure to draw
|
||||
ax = plt.axes() # create an axes object
|
||||
|
||||
def animate(i):
|
||||
ax.clear() # clear axes object
|
||||
ax.set_xticks([], []) # clear x-axis ticks
|
||||
ax.set_yticks([], []) # clear y-axis ticks
|
||||
|
||||
X = np.empty((len(re), len(im))) # re-initialize the array-like image
|
||||
threshold = round(1.15 ** (i + 1)) # calculate the current threshold
|
||||
|
||||
# iterations for the current threshold
|
||||
for i in range(len(re)):
|
||||
for j in range(len(im)):
|
||||
X[i, j] = mandelbrot(re[i], im[j], threshold)
|
||||
|
||||
# associate colors to the iterations with an iterpolation
|
||||
img = ax.imshow(X.T, interpolation="bicubic", cmap='magma')
|
||||
|
||||
return [img]
|
||||
|
||||
anim = animation.FuncAnimation(fig, animate, frames=45, interval=120, blit=True)
|
||||
return anim
|
BIN
bell/417116__dersinnsspace__tibetan-bowl_right-hit-mod.wav
Normal file
BIN
bell/417116__dersinnsspace__tibetan-bowl_right-hit-mod.wav
Normal file
Binary file not shown.
47
main.py
47
main.py
|
@ -9,6 +9,7 @@ from AccelBrainBeat.brainbeat.binaural_beat import BinauralBeat
|
|||
import pydub
|
||||
import random
|
||||
|
||||
from animate_fractal import animategif
|
||||
from blend_av import blend_av
|
||||
|
||||
app = FastAPI()
|
||||
|
@ -37,7 +38,7 @@ class VideoProperties(BaseModel):
|
|||
main_frequency: int
|
||||
breath_pattern_in: int
|
||||
breath_pattern_out: int
|
||||
color_palette = str
|
||||
color_scheme = str
|
||||
|
||||
|
||||
class AvProperties(BaseModel):
|
||||
|
@ -66,12 +67,11 @@ async def get_generate_audio(audio_properties: AudioProperties):
|
|||
:param audio_properties:
|
||||
:return:
|
||||
"""
|
||||
# Generate a random 32 hexadecimal string
|
||||
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):
|
||||
os.remove(str(tmp_dir / filename))
|
||||
os.remove(tmp_dir / str(filename))
|
||||
bell_dir = pathlib.Path("bell")
|
||||
filename_prefix = ''.join([random.choice('0123456789ABCDEF') for i in range(32)])
|
||||
filename = f"{filename_prefix}.wav"
|
||||
|
@ -80,18 +80,32 @@ async def get_generate_audio(audio_properties: AudioProperties):
|
|||
b.save_beat(output_file_name=str(tmp_dir / "binaural_beat.wav"),
|
||||
frequencys=(audio_properties.main_frequency,
|
||||
audio_properties.lag_frequency),
|
||||
play_time=(audio_properties.breath_pattern_in + audio_properties.breath_pattern_out)*2,
|
||||
play_time=(audio_properties.breath_pattern_in + audio_properties.breath_pattern_out) * 2,
|
||||
volume=audio_properties.volume
|
||||
)
|
||||
pydub_background = pydub.AudioSegment.from_wav(tmp_dir / "binaural_beat.wav")
|
||||
pydub_bell = pydub.AudioSegment.from_wav(bell_dir / audio_properties.bell_sound)
|
||||
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)
|
||||
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)
|
||||
pydub_mix.export(tmp_dir / filename, format="wav")
|
||||
return filename
|
||||
return FileResponse(tmp_dir / filename)
|
||||
|
||||
|
||||
@app.get("/generate_video")
|
||||
|
@ -101,7 +115,16 @@ async def get_generate_video(video_properties: VideoProperties):
|
|||
:param video_properties:
|
||||
:return:
|
||||
"""
|
||||
return None
|
||||
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))
|
||||
|
||||
|
||||
@app.get("/generate_av")
|
||||
|
|
21
mandelbrot.py
Normal file
21
mandelbrot.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Source: https://matplotlib.org/matplotblog/posts/animated-fractals/
|
||||
def mandelbrot(x, y, threshold):
|
||||
"""Calculates whether the number c = x + i*y belongs to the
|
||||
Mandelbrot set. In order to belong, the sequence z[i + 1] = z[i]**2 + c
|
||||
must not diverge after 'threshold' number of steps. The sequence diverges
|
||||
if the absolute value of z[i+1] is greater than 4.
|
||||
|
||||
:param float x: the x component of the initial complex number
|
||||
:param float y: the y component of the initial complex number
|
||||
:param int threshold: the number of iterations to considered it converged
|
||||
"""
|
||||
# initial conditions
|
||||
c = complex(x, y)
|
||||
z = complex(0, 0)
|
||||
|
||||
for i in range(threshold):
|
||||
z = z ** 2 + c
|
||||
if abs(z) > 4.: # it diverged
|
||||
return i
|
||||
|
||||
return threshold - 1 # it didn't diverge
|
|
@ -5,3 +5,5 @@ starlette~=0.26.1
|
|||
AccelBrainBeat~=1.0.5
|
||||
httpx~=0.23.3
|
||||
pydub~=0.25.1
|
||||
numpy~=1.24.2
|
||||
matplotlib~=3.7.1
|
Loading…
Reference in a new issue