Beim KlavierübenTEMPO(eine App für iOS, CHplay) ist ein Metronom, das oft verwendet wird, um im Takt zu schlagen.
Ich kann animierte GIF/PDF/SVG/Frames (in beamer
) für TEMPO erstellen, weiß aber nicht, wie ich einen Ton abspielen kann (z. B. Beep 8 mp3
oder wav
inHier) bei jedem Schlag.
Kann jemand helfen (mit vollständigem Code und klarer Erklärung)? Danke!
Der folgende Code sind meine MWEs. (das sind gute Beispiele für animierte Dinge)
% TEMPO for piano tempo.tex
% for animated GIF, run on command line (require ImageMagick installed)
% magick -density 200 -delay 100 tempo.pdf tempo.gif
% -delay 100 >>> each frame is 100/100 = 1 second
\documentclass[tikz]{standalone}
\begin{document}
\foreach \n in {1,...,4}{
\pagecolor{white}
\begin{tikzpicture}
\path (0,-1) rectangle (5,1);
\shade[inner color=green,outer color=green!10]
(\n,0) circle(.5);
\foreach \i in {1,...,4}
\fill[cyan] (\i,0) circle(.3);
\end{tikzpicture}
}
\end{document}
Mit geringfügigen Änderungen können wir ein animiertes PDF erhalten (im Acrobat Reader öffnen).
% animated PDF standalone tempopdf.tex
% \multiframe{4}{n=1+1} >>> starting frame is with n=1,
% then plus 1 each frame, so we have 4 frames
% [loop,controls]{1} >>> number 1 means 1 second each frame
\documentclass{standalone}
\usepackage{tikz}
\usepackage{animate}
\begin{document}
\begin{animateinline}[loop,controls]{1}
\multiframe{4}{n=1+1}
{
\begin{tikzpicture}
\path (0,-1) rectangle (5,1);
\shade[inner color=green,outer color=green!10]
(\n,0) circle(.6);
\foreach \i in {1,...,4}
\fill[cyan] (\i,0) circle(.3);
\end{tikzpicture}
}
\end{animateinline}
\end{document}
Animierter PDF-Rahmen im Beamer (öffnen mit Acrobat Reader)
% animated PDF frame in beamer (open with Acrobat Reader)
\documentclass{beamer}
\usepackage{tikz}
\usepackage{animate}
\usepackage{multimedia}
\begin{document}
\begin{frame}{TEMPO for piano}
\begin{center}
\begin{animateinline}[loop,controls]{1}
\multiframe{4}{n=1+1}
{
\begin{tikzpicture}
\path (0,-1) rectangle (5,1);
\shade[inner color=green,outer color=green!10] (\n,0) circle(.6);
\foreach \i in {1,...,4} \fill[cyan] (\i,0) circle(.3);
\end{tikzpicture}
}
\end{animateinline}
\end{center}
\end{frame}
\end{document}
Antwort1
KlickenKlicken Sie auf das Bild unten, um das tickende Metronom (SVG-Version) in Aktion zu sehen:
Dieses animate
auf -basierte Beispiel gibt es in zwei Versionen.
DerPDFDie Version erfordert Acrobat Reader und ist daher auf Windows- und OSX-Plattformen für Desktop-PCs beschränkt. (Mobile Geräte werden nicht unterstützt.) Die PDF-Version verwendet media9
zum Abspielen die eingebettete Sounddateiclick.mp3
, entnommen aus dem animate
Paket, dessen Handbuch bereits ein Beispiel für ein tickendes Metronom enthält.
Der StandaloneSVGDie Version läuft in den meisten aktuellen Webbrowsern (Firefox, Chrome, Opera ...), auch auf Mobilgeräten. Dabei wird der Ton mithilfe des HTML5- <audio>
Tags als Base64-codierter Blob eingebettet. ( click.mp3
wurde mit " " in der Befehlszeile codiert base64 click.mp3
.) Die physisch eingebettete Sounddatei macht das SVG in sich geschlossen.
In beiden Fällen wird die Wiedergabe des Sounds bei jedem Framewechsel der laufenden Animation durch JavaScript gestartet. Die Funktion „Timeline“ von animate
wird verwendet, um den JS-Code jedem Frame zuzuordnen (Timeline-Input frames.txt
).
Der Tempomarker wird mit einer zweiten animateinline
Umgebung implementiert. Er bietet 39 typische Metronomgeschwindigkeiten, die mit den +/- Schaltflächen durchgeschaltet werden können. Die Schaltflächen verwenden die animate
JavaScript-Schnittstelle, um die Framenummer des Tempomarkers zu erhöhen und zu verringern. Eine weitere Timeline-Datei, tempo.txt
, verknüpft jeden Marker-Frame mit einem JS-Snippet, das die Metronomgeschwindigkeit entsprechend skaliert, wiederum unter Verwendung der JS-Schnittstelle von animate
.
PDFVersion, zu kompilieren mit pdflatex
, lualatex
, latex+dvips+ps2pdf
, oder xelatex
:
\documentclass[varwidth,border=12pt]{standalone}
\usepackage{tikz}
\usepackage{animate}
\usepackage{media9}
\usepackage{fontawesome5}
% tempo markers
\def\tempos{{40,42,44,46,48,50,52,54,56,58,60,63,66,69,72,76,80,84,88,92,96,100,104,108,112,116,120,126,132,138,144,152,160,168,176,184,192,200,208}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% timeline files
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% metronome
\usepackage{filecontents}
\begin{filecontents*}{frames.txt}
::0: annotRM['click'].callAS('play');
::1: annotRM['click'].callAS('play');
::2: annotRM['click'].callAS('play');
::3: annotRM['click'].callAS('play');
\end{filecontents*}
% tempo
\newwrite\TimeLineFile
\immediate\openout\TimeLineFile=tempo.txt
\foreach \i in {0,1,...,38} {
%JavaScript for scaling the metronome's default speed (60 frames per min)
\pgfmathparse{\tempos[\i]/60}
\immediate\write\TimeLineFile{::\i:anim.metronome.speed=\pgfmathresult;}
}
\immediate\closeout\TimeLineFile
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\setlength{\textwidth}{4.4cm}
\begin{document}
\begin{center}
%the sound player
\makebox[0pt][r]{\includemedia[
width=1ex,height=1ex,
label=click,
addresource=click.mp3,
activate=pageopen,transparent,noplaybutton,
flashvars={source=click.mp3&hideBar=true}
]{}{APlayer.swf}}%
\makebox[4cm][l]{The \LaTeX{} Metronome}\\[1ex]
%%%%%%%%%%%
% metronome
%%%%%%%%%%%
\begin{animateinline}[label=metronome,nomouse,loop,timeline=frames.txt]{1}
\multiframe{4}{n=1+1}{
\begin{tikzpicture}
\path (0.3,-0.5) rectangle (4.7,0.5);
\shade[inner color=green,outer color=green!10] (\n,0) circle(.6);
\foreach \i in {1,...,4} \fill[cyan] (\i,0) circle(.3);
\end{tikzpicture}
}
\end{animateinline}
%%%%%%%%%%%
% controls
%%%%%%%%%%%
\makebox[4cm]{%
\mediabutton[
jsaction={
if(anim.metronome.isPlaying) anim.metronome.stopFirst();
else anim.metronome.playFwd();
}
]{\faPowerOff}\hfill
% tempo
\mediabutton[
jsaction={ try {--anim.tempo.frameNum;} catch (e) {} }
]{\faMinusCircle}\,%
\begin{animateinline}[label=tempo,step,nomouse,poster=10,timeline=tempo.txt]{1}
\multiframe{39}{i=0+1}{
\pgfmathparse{\tempos[\i]}
\makebox[\widthof{000}][c]{\strut\pgfmathresult}
}
\end{animateinline}\,%
\mediabutton[
jsaction={ try {++anim.tempo.frameNum;} catch (e) {} }
]{\faPlusCircle}}
\end{center}
\end{document}
SVGVersion, zu kompilieren mit
latex tempoForWeb.tex
latex tempoForWeb.tex
dvisvgm --font-format=woff --exact --zoom=-1 tempoForWeb.dvi
Das SVG kann eigenständig in einem Webbrowser angezeigt oder mithilfe des <object>
HTML-Tags in eine Webseite eingebettet werden:
\documentclass[dvisvgm,varwidth,preview]{standalone}
\usepackage{tikz}
\usepackage{animate}
\usepackage{fontawesome5}
% tempo markers
\def\tempos{{40,42,44,46,48,50,52,54,56,58,60,63,66,69,72,76,80,84,88,92,96,100,104,108,112,116,120,126,132,138,144,152,160,168,176,184,192,200,208}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% timeline files
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% metronome
\usepackage{filecontents}
\begin{filecontents*}{frames.txt}
::0:$('click').play();
::1:$('click').play();
::2:$('click').play();
::3:$('click').play();
\end{filecontents*}
% tempo
\newwrite\TimeLineFile
\immediate\openout\TimeLineFile=tempo.txt
\foreach \i in {0,1,...,38} {
%JavaScript for scaling the metronome's default speed (60 frames per min)
\pgfmathparse{\tempos[\i]/60}
\immediate\write\TimeLineFile{::\i:anim.metronome.speed=\pgfmathresult;}
}
\immediate\closeout\TimeLineFile
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for producing push buttons
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOn
\def\controlButton#1#2{% #1:button face, #2 JavaScript
\sbox{0}{#1}
\makebox[0pt][l]{\usebox{0}}
\pbs_pdfannot:nnnn{\wd0}{\ht0}{\dp0}{cursor='pointer'~onmousedown='#2'}
\phantom{\usebox{0}}
}
\ExplSyntaxOff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\setlength{\textwidth}{4.4cm}
\begin{document}
% embed sound
\special{dvisvgm:rawdef
<audio xmlns="http://www.w3.org/1999/xhtml" id='click'>
<source
src="data:audio/mpeg;base64,
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
qqqqqqqqqqqq" type="audio/mpeg"/>
% <source src="click.mp3" type="audio/mpeg"/> % alternatively: separate mp3
</audio>
<script type="text/javascript">
<![CDATA[
function $(id) {return document.getElementById(id);};
]]>
</script>
}
\begin{center}
\makebox[4cm][l]{The \LaTeX{} Metronome}\\[1ex]
%%%%%%%%%%%
% metronome
%%%%%%%%%%%
\begin{animateinline}[label=metronome,nomouse,loop,timeline=frames.txt]{1}
\multiframe{4}{n=1+1}{
\begin{tikzpicture}
\path (0.3,-0.5) rectangle (4.7,0.5);
\shade[inner color=green,outer color=green!10] (\n,0) circle(.6);
\foreach \i in {1,...,4} \fill[cyan] (\i,0) circle(.3);
\end{tikzpicture}
}
\end{animateinline}
%%%%%%%%%%%
% controls
%%%%%%%%%%%
\makebox[4cm]{%
\controlButton{\faPowerOff}{%
if(anim.metronome.isPlaying) anim.metronome.stopFirst();
else anim.metronome.playFwd();
}\hfill
% tempo
\controlButton{\faMinusCircle}{%
try {--anim.tempo.frameNum;} catch (e) {}
}\,%
\begin{animateinline}[label=tempo,step,nomouse,poster=10,timeline=tempo.txt]{1}
\multiframe{39}{i=0+1}{
\pgfmathparse{\tempos[\i]}
\makebox[\widthof{000}][c]{\strut\pgfmathresult}
}
\end{animateinline}\,%
\controlButton{\faPlusCircle}{%
try {++anim.tempo.frameNum;} catch (e) {}
}}
\end{center}
\end{document}
Standalone, animiertGIFist meines Wissens nach stumm und taub, und es scheint keine leicht zugängliche Methode zu geben, ein eingebettetes Gif (in einer Webseite) mit einem Ton zu synchronisieren. AberSVGist deutlich überlegen, da es vektoriell und somit frei skalierbar ist.
Antwort2
Alternativ können Sie die Animation auch woanders mit Ton erstellen und den Beamer-Dateien hinzufügen. Beamer scheint ein Multimedia-Paket zu haben. Auch movie15 scheint vielversprechend zu sein.
Schauen Sie sich diesen Thread über Multimedia/Sound anSo fügen Sie eine Audiodatei in eine PDF-Datei ein, vielleicht ist das ein gültiger Ausgangspunkt.