Coverage for src\simplestretch\__init__.py: 100%
29 statements
« prev ^ index » next coverage.py v7.5.3, created at 2024-06-08 17:18 +0100
« prev ^ index » next coverage.py v7.5.3, created at 2024-06-08 17:18 +0100
1from typing import Optional, Tuple, Union
3import soundfile
4from numpy import ndarray
5import pathlib
8def stretch_audio(
9 audio: Union[str, ndarray],
10 factor: float,
11 output: Optional[str] = None,
12 samplerate: Optional[int] = None,
13) -> Tuple[ndarray, int]:
14 """This function is used to stretch an audio's length by a certain factor.\n
15 Because this function doesn't apply any resampling or similar algorithms, for very high factors (around 5 or higher) the audio quality might decrease noticeably.
17 :param audio: The audio to be stretched.\n
18 You can provide either a path to a file containing your audio, or the raw sound data as a numpy ndarray.
19 :type audio: str | numpy.ndarray
21 :param factor: This is the factor by which the length of the audio will be changed.\n
22 For example, a factor of 2 will make the audio twice as long, and a factor of 0.5 will make the audio half as long.
23 :type factor: float
25 :param output: This is the path to which the stretched audio will be saved.\n
26 If no argument is passed, it wont save the audio to a file.
27 :type output: str, optional
29 :param samplerate: The sample rate of the original audio.\n
30 You only need to pass this argument if you've provided a numpy ndarray as the audio. Otherwise, it will be determined automatically.
31 :type samplerate: int, optional
33 :return: A tuple containing the stretched audio data and sample rate.\n
34 This is returned whether or not the audio gets saved to a file.
35 :rtype: Tuple[ndarray, int]
37 """
39 # Type checks
40 if not (isinstance(audio, str) or isinstance(audio, ndarray)):
41 raise TypeError("'audio' must be the path to a audio file or a numpy ndarray")
43 if factor <= 0:
44 raise ValueError("'factor' must be greater than 0")
46 if isinstance(audio, ndarray) and not isinstance(samplerate, int):
47 try:
48 samplerate = int(samplerate)
49 except:
50 raise TypeError(f"You must provide a valid sample rate when working with raw audio data (Not {type(samplerate)})")
53 # If a file path is provided, load it as a ndarray using soundfile
54 if isinstance(audio, str):
55 audio, samplerate = soundfile.read(audio)
57 stretched_samplerate = round(samplerate / factor)
59 if isinstance(output, str):
60 try:
61 soundfile.write(output, audio, samplerate=stretched_samplerate)
62 except soundfile.LibsndfileError as exc:
63 # Delete invalid file
64 pathlib.Path(output).unlink()
66 exc.add_note("(Try saving it as a .wav file instead)")
67 raise exc
69 return (audio, stretched_samplerate)
72def speedup_audio(
73 audio: Union[str, ndarray],
74 factor: float,
75 output: Optional[str] = None,
76 samplerate: Optional[int] = None,
77) -> Tuple[ndarray, int]:
78 """This function is used to change an audio's speed by a certain factor.\n
79 Because this function doesn't apply any resampling or similar algorithms, for very low factors (around 0.2 or lower) the audio quality might decrease noticeably.
81 :param audio: The audio to be sped up or down.\n
82 You can provide either a path to a file containing your audio, or the raw sound data as a numpy ndarray.
83 :type audio: str | numpy.ndarray
85 :param factor: This is the factor by which the speed of the audio will be changed.\n
86 For example, a factor of 2 will make the audio twice as fast, and a factor of 0.5 will make the audio half as fast.
87 :type factor: float
89 :param output: This is the path to which the sped up audio will be saved.\n
90 If no argument is passed, it wont save the audio to a file.
91 :type output: str, optional
93 :param samplerate: The sample rate of the original audio.\n
94 You only need to pass this argument if you've provided a numpy ndarray as the audio. Otherwise, it will be determined automatically.
95 :type samplerate: int, optional
97 :return: A tuple containing the sped up audio data and sample rate.\n
98 This is returned whether or not the audio gets saved to a file.
99 :rtype: Tuple[ndarray, int]
101 """
103 # Type checks
104 if factor <= 0:
105 raise ValueError("'factor' must be greater than 0")
107 # Stretch audio to match the specified speedup factor
108 return stretch_audio(
109 audio=audio, factor=1 / factor, output=output, samplerate=samplerate
110 )