fat-llama 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, Raad
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,5 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ recursive-include fat_llama/tests *
5
+ recursive-include fat_llama/audio_fattener *
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.1
2
+ Name: fat_llama
3
+ Version: 0.1.2
4
+ Summary: A package for CUDA-based upscaling and processing audio files, using FFT to add audio frequency details after upscaling.
5
+ Home-page: https://github.com/bkraad47/fat_llama
6
+ Author: Badruddin Kamal
7
+ Author-email: bulkguy47@gmail.com
8
+ License: BSD-3-Clause
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: BSD License
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: numpy
20
+ Requires-Dist: cupy-cuda12x
21
+ Requires-Dist: pydub
22
+ Requires-Dist: soundfile
23
+ Requires-Dist: mutagen
24
+ Requires-Dist: scipy
25
+ Requires-Dist: tqdm
26
+
27
+ # fat_llama
28
+
29
+ fat_llama is a Python package for upscaling MP3 files to FLAC format using advanced audio processing techniques. It utilizes GPU-accelerated calculations to enhance audio quality by upsampling and adding missing frequencies, resulting in richer and more detailed audio.
30
+
31
+ ## Features
32
+
33
+ - Upscale MP3 files to high-quality FLAC format.
34
+ - Optional iterative soft thresholding (IST) for enhanced audio processing.
35
+ - Gain adjustment, equalization, and optional Wiener filtering.
36
+ - Supports GPU-accelerated processing with CuPy.
37
+
38
+ ## Installation
39
+
40
+ Clone the repository:
41
+
42
+ Install:
43
+ ```
44
+ pip install fat_llama-0.1.0
45
+ ```
46
+ Further need CUDA & CuPy properly installed: https://docs.cupy.dev/en/stable/install.html
47
+
48
+ Also, requires ffmpeg for windows: https://support.audacityteam.org/basics/installing-ffmpeg
49
+ ## Usage
50
+ ### Example Usage
51
+ You can run the example provided in example.py:
52
+
53
+ ```
54
+ from fat_llama.audio_fattener import upscale_mp3_to_flac
55
+
56
+ # Example call to the method
57
+ upscale_mp3_to_flac(
58
+ input_file_path='input_short.mp3',
59
+ output_file_path_processed='output_processed.flac',
60
+ max_iterations=400,
61
+ threshold_value=0.4,
62
+ gain_factor=22.8,
63
+ reduction_profile=[
64
+ (5, 140, -28.4),
65
+ (1000, 10000, 26.4),
66
+ ],
67
+ lowcut=5.0,
68
+ highcut=150000.0,
69
+ target_bitrate_kbps=1400,
70
+ output_file_path_no_processing='output_upscaled_no_processing.flac',
71
+ use_wiener_filter=False
72
+ )
73
+ ```
74
+ ### Function Parameters
75
+ input_file_path (str): Path to the input MP3 file. Mandatory.
76
+ output_file_path_processed (str): Path to the output processed FLAC file. Mandatory.
77
+ max_iterations (int): Number of iterations for IST. Default is 400.
78
+ threshold_value (float): Threshold value for IST. Default is 0.4.
79
+ gain_factor (float): Gain factor for scaling amplitude. Default is 22.8.
80
+ reduction_profile (list): Profile for gain reduction. Default is [(5, 140, -28.4), (1000, 10000, 26.4)].
81
+ lowcut (float): Low cut frequency for equalizer. Default is 5.0.
82
+ highcut (float): High cut frequency for equalizer. Default is 150000.0.
83
+ target_bitrate_kbps (int): Target bitrate in kbps. Default is 1400.
84
+ output_file_path_no_processing (str): Path to the output upscaled (no processing) FLAC file. Default is None.
85
+ use_wiener_filter (bool): Flag to use Wiener filter. Default is False.
86
+
87
+ ## Running the Example
88
+ To run the example, execute the following command:
89
+ ```
90
+ python example.py
91
+ ```
92
+ This will upscale the MP3 file specified in the example and produce two FLAC files: one with just upscaling and one with full processing.
93
+
94
+ ## Algorithm Explanation
95
+ The upscaling process involves several steps:
96
+
97
+ 1. Reading MP3 File: The MP3 file is read, and the audio samples are extracted along with the sample rate and bitrate.
98
+ 2. Calculating Upscale Factor: The upscale factor is calculated to achieve the target bitrate.
99
+ 3. Upscaling Channels: The audio channels are upscaled using an interpolation algorithm. Each sample is repeated multiple times to increase the resolution.
100
+ 4. Iterative Soft Thresholding (IST): IST is applied to enhance the audio by adding missing frequencies. This process uses FFT to transform the signal into the frequency domain, apply a threshold to keep significant frequencies, and then inverse transform back to the time domain.
101
+ 5. Scaling Amplitude: The amplitude of the upscaled audio is scaled to match the original.
102
+ 6. Applying Gain Reduction: Frequency-specific gain reduction is applied based on a given profile.
103
+ 7. Equalization: A bandpass filter is applied to the audio to equalize it.
104
+ 8. Optional Wiener Filtering: Wiener filtering is applied to reduce noise if specified.
105
+ 9. Writing FLAC File: The processed audio is written to a FLAC file.
106
+
107
+ ## Why FFT and IST?
108
+ FFT (Fast Fourier Transform) is used to transform the audio signal into the frequency domain. This allows for the identification and manipulation of specific frequency components. By applying a threshold in the frequency domain, we can keep significant frequencies and discard noise and add it to our upscaling data to add detail to upscaling frequencies.
109
+
110
+ The report titled "Fast Sparse Fourier Transformations for NMR Spectroscopy" by Badruddin Kamal, supervised by Thomas Huber and Alastair Rendall, 2015, provides a comprehensive understanding of sparse representations and their applications in signal processing. IST leverages the concepts from this report to add missing frequencies and enhance the audio quality by making it more detailed and rich. This is particularly useful in upscaling audio where some frequencies might be missing or congested.
111
+
112
+ ### Test Audio Source, ericzo - beyond link(https://soundcloud.com/ericzomusic/free-electro-trap-anthem-beyond)
@@ -0,0 +1,86 @@
1
+ # fat_llama
2
+
3
+ fat_llama is a Python package for upscaling MP3 files to FLAC format using advanced audio processing techniques. It utilizes GPU-accelerated calculations to enhance audio quality by upsampling and adding missing frequencies, resulting in richer and more detailed audio.
4
+
5
+ ## Features
6
+
7
+ - Upscale MP3 files to high-quality FLAC format.
8
+ - Optional iterative soft thresholding (IST) for enhanced audio processing.
9
+ - Gain adjustment, equalization, and optional Wiener filtering.
10
+ - Supports GPU-accelerated processing with CuPy.
11
+
12
+ ## Installation
13
+
14
+ Clone the repository:
15
+
16
+ Install:
17
+ ```
18
+ pip install fat_llama-0.1.0
19
+ ```
20
+ Further need CUDA & CuPy properly installed: https://docs.cupy.dev/en/stable/install.html
21
+
22
+ Also, requires ffmpeg for windows: https://support.audacityteam.org/basics/installing-ffmpeg
23
+ ## Usage
24
+ ### Example Usage
25
+ You can run the example provided in example.py:
26
+
27
+ ```
28
+ from fat_llama.audio_fattener import upscale_mp3_to_flac
29
+
30
+ # Example call to the method
31
+ upscale_mp3_to_flac(
32
+ input_file_path='input_short.mp3',
33
+ output_file_path_processed='output_processed.flac',
34
+ max_iterations=400,
35
+ threshold_value=0.4,
36
+ gain_factor=22.8,
37
+ reduction_profile=[
38
+ (5, 140, -28.4),
39
+ (1000, 10000, 26.4),
40
+ ],
41
+ lowcut=5.0,
42
+ highcut=150000.0,
43
+ target_bitrate_kbps=1400,
44
+ output_file_path_no_processing='output_upscaled_no_processing.flac',
45
+ use_wiener_filter=False
46
+ )
47
+ ```
48
+ ### Function Parameters
49
+ input_file_path (str): Path to the input MP3 file. Mandatory.
50
+ output_file_path_processed (str): Path to the output processed FLAC file. Mandatory.
51
+ max_iterations (int): Number of iterations for IST. Default is 400.
52
+ threshold_value (float): Threshold value for IST. Default is 0.4.
53
+ gain_factor (float): Gain factor for scaling amplitude. Default is 22.8.
54
+ reduction_profile (list): Profile for gain reduction. Default is [(5, 140, -28.4), (1000, 10000, 26.4)].
55
+ lowcut (float): Low cut frequency for equalizer. Default is 5.0.
56
+ highcut (float): High cut frequency for equalizer. Default is 150000.0.
57
+ target_bitrate_kbps (int): Target bitrate in kbps. Default is 1400.
58
+ output_file_path_no_processing (str): Path to the output upscaled (no processing) FLAC file. Default is None.
59
+ use_wiener_filter (bool): Flag to use Wiener filter. Default is False.
60
+
61
+ ## Running the Example
62
+ To run the example, execute the following command:
63
+ ```
64
+ python example.py
65
+ ```
66
+ This will upscale the MP3 file specified in the example and produce two FLAC files: one with just upscaling and one with full processing.
67
+
68
+ ## Algorithm Explanation
69
+ The upscaling process involves several steps:
70
+
71
+ 1. Reading MP3 File: The MP3 file is read, and the audio samples are extracted along with the sample rate and bitrate.
72
+ 2. Calculating Upscale Factor: The upscale factor is calculated to achieve the target bitrate.
73
+ 3. Upscaling Channels: The audio channels are upscaled using an interpolation algorithm. Each sample is repeated multiple times to increase the resolution.
74
+ 4. Iterative Soft Thresholding (IST): IST is applied to enhance the audio by adding missing frequencies. This process uses FFT to transform the signal into the frequency domain, apply a threshold to keep significant frequencies, and then inverse transform back to the time domain.
75
+ 5. Scaling Amplitude: The amplitude of the upscaled audio is scaled to match the original.
76
+ 6. Applying Gain Reduction: Frequency-specific gain reduction is applied based on a given profile.
77
+ 7. Equalization: A bandpass filter is applied to the audio to equalize it.
78
+ 8. Optional Wiener Filtering: Wiener filtering is applied to reduce noise if specified.
79
+ 9. Writing FLAC File: The processed audio is written to a FLAC file.
80
+
81
+ ## Why FFT and IST?
82
+ FFT (Fast Fourier Transform) is used to transform the audio signal into the frequency domain. This allows for the identification and manipulation of specific frequency components. By applying a threshold in the frequency domain, we can keep significant frequencies and discard noise and add it to our upscaling data to add detail to upscaling frequencies.
83
+
84
+ The report titled "Fast Sparse Fourier Transformations for NMR Spectroscopy" by Badruddin Kamal, supervised by Thomas Huber and Alastair Rendall, 2015, provides a comprehensive understanding of sparse representations and their applications in signal processing. IST leverages the concepts from this report to add missing frequencies and enhance the audio quality by making it more detailed and rich. This is particularly useful in upscaling audio where some frequencies might be missing or congested.
85
+
86
+ ### Test Audio Source, ericzo - beyond link(https://soundcloud.com/ericzomusic/free-electro-trap-anthem-beyond)
File without changes
File without changes
@@ -0,0 +1,305 @@
1
+ import numpy as np
2
+ import cupy as cp
3
+ from pydub import AudioSegment
4
+ import soundfile as sf
5
+ import os
6
+ import logging
7
+ from mutagen.mp3 import MP3
8
+ from scipy.signal import butter, lfilter, sosfilt, wiener
9
+ import traceback
10
+
11
+ # Setup logging
12
+ logging.basicConfig(level=logging.INFO)
13
+ logger = logging.getLogger(__name__)
14
+
15
+ def read_mp3(file_path):
16
+ """
17
+ Read an MP3 file and return the sample rate and data as a NumPy array
18
+
19
+ Parameters:
20
+ file_path (str): The path to the input MP3 file.
21
+
22
+ Returns:
23
+ int: Sample rate of the audio.
24
+ numpy.ndarray: Audio samples.
25
+ int: Bitrate of the MP3 file.
26
+ AudioSegment: The audio segment object.
27
+ """
28
+ if not os.path.exists(file_path):
29
+ raise FileNotFoundError(f"File {file_path} not found.")
30
+ audio = AudioSegment.from_mp3(file_path)
31
+ samples = np.array(audio.get_array_of_samples())
32
+ sample_rate = audio.frame_rate
33
+ mp3_info = MP3(file_path)
34
+ bitrate = mp3_info.info.bitrate
35
+ if audio.channels == 2:
36
+ samples = samples.reshape((-1, 2))
37
+ return sample_rate, samples, bitrate, audio
38
+
39
+ def write_flac(file_path, sample_rate, data):
40
+ """
41
+ Write data to a FLAC file
42
+
43
+ Parameters:
44
+ file_path (str): The path to the output FLAC file.
45
+ sample_rate (int): The sample rate of the audio.
46
+ data (numpy.ndarray): The audio data to write.
47
+ """
48
+ sf.write(file_path, data.astype(np.float32), sample_rate, format='FLAC', subtype='PCM_24')
49
+
50
+ def new_interpolation_algorithm(data, upscale_factor):
51
+ """
52
+ Interpolate data with scaled changes around center points
53
+
54
+ Parameters:
55
+ data (numpy.ndarray): The input audio data.
56
+ upscale_factor (int): The factor by which to upscale the audio data.
57
+
58
+ Returns:
59
+ numpy.ndarray: The upscaled audio data.
60
+ """
61
+ original_length = len(data)
62
+ expanded_length = original_length * upscale_factor
63
+ expanded_data = np.zeros(expanded_length, dtype=np.float32)
64
+
65
+ for i in range(original_length):
66
+ center_point = data[i]
67
+ for j in range(upscale_factor):
68
+ index = i * upscale_factor + j
69
+ expanded_data[index] = center_point
70
+
71
+ return expanded_data
72
+
73
+ def initialize_ist(data, threshold):
74
+ """
75
+ Initialize IST variables
76
+
77
+ Parameters:
78
+ data (cupy.ndarray): The input audio data.
79
+ threshold (float): The threshold value for IST.
80
+
81
+ Returns:
82
+ cupy.ndarray: The thresholded audio data.
83
+ """
84
+ mask = cp.abs(data) > threshold
85
+ data_thres = cp.where(mask, data, 0)
86
+ return data_thres
87
+
88
+ def iterative_soft_thresholding(data, max_iter, threshold):
89
+ """
90
+ Perform IST on data using CuPy and cuFFT
91
+
92
+ Parameters:
93
+ data (numpy.ndarray): The input audio data.
94
+ max_iter (int): The maximum number of iterations for IST.
95
+ threshold (float): The threshold value for IST.
96
+
97
+ Returns:
98
+ numpy.ndarray: The processed audio data after IST.
99
+ """
100
+ data_cp = cp.array(data, dtype=cp.float32)
101
+ data_thres = initialize_ist(data_cp, threshold)
102
+ for _ in range(max_iter):
103
+ data_fft = cp.fft.fft(data_thres)
104
+ mask = cp.abs(data_fft) > threshold
105
+ data_fft_thres = cp.where(mask, data_fft, 0)
106
+ data_thres = cp.fft.ifft(data_fft_thres).real
107
+ return cp.asnumpy(data_thres)
108
+
109
+ def upscale_channels(channels, upscale_factor, max_iter, threshold, apply_ist=True):
110
+ """
111
+ Process and upscale channels using the new interpolation and IST algorithms
112
+
113
+ Parameters:
114
+ channels (numpy.ndarray): The input audio channels.
115
+ upscale_factor (int): The factor by which to upscale the audio data.
116
+ max_iter (int): The maximum number of iterations for IST.
117
+ threshold (float): The threshold value for IST.
118
+ apply_ist (bool): Flag to apply IST or not.
119
+
120
+ Returns:
121
+ numpy.ndarray: The upscaled (and processed, if apply_ist=True) audio data.
122
+ """
123
+ processed_channels = []
124
+ for channel in channels.T:
125
+ logger.info("Interpolating data...")
126
+ expanded_channel = new_interpolation_algorithm(channel, upscale_factor)
127
+
128
+ if apply_ist:
129
+ logger.info("Performing IST...")
130
+ ist_changes = iterative_soft_thresholding(expanded_channel, max_iter, threshold)
131
+ expanded_channel = expanded_channel.astype(np.float32) + ist_changes
132
+
133
+ processed_channels.append(expanded_channel)
134
+
135
+ return np.column_stack(processed_channels)
136
+
137
+ def normalize_signal(signal):
138
+ """
139
+ Normalize signal to the range -1 to 1
140
+
141
+ Parameters:
142
+ signal (numpy.ndarray): The input audio signal.
143
+
144
+ Returns:
145
+ numpy.ndarray: The normalized audio signal.
146
+ """
147
+ return signal / np.max(np.abs(signal))
148
+
149
+ def scale_amplitude(original, upscaled, gain_factor):
150
+ """
151
+ Scale the amplitude of the upscaled channels to match the original and apply gain factor
152
+
153
+ Parameters:
154
+ original (numpy.ndarray): The original audio data.
155
+ upscaled (numpy.ndarray): The upscaled audio data.
156
+ gain_factor (float): The gain factor to apply.
157
+
158
+ Returns:
159
+ numpy.ndarray: The scaled upscaled audio data.
160
+ """
161
+ normalized_original = normalize_signal(original)
162
+ normalized_upscaled = normalize_signal(upscaled)
163
+
164
+ scale_factor = np.max(np.abs(normalized_original)) / np.max(np.abs(normalized_upscaled))
165
+ scaled_upscaled = normalized_upscaled * scale_factor * gain_factor
166
+
167
+ return scaled_upscaled
168
+
169
+ def apply_gain_reduction(data, sample_rate, reduction_profile):
170
+ """
171
+ Apply gain reduction based on the given reduction profile
172
+
173
+ Parameters:
174
+ data (cupy.ndarray): The input audio data.
175
+ sample_rate (int): The sample rate of the audio.
176
+ reduction_profile (list of tuple): The reduction profile as a list of (lowcut, highcut, reduction_factor) tuples.
177
+
178
+ Returns:
179
+ numpy.ndarray: The gain-reduced audio data.
180
+ """
181
+ nyquist = 0.5 * sample_rate
182
+ reduced_data = cp.asnumpy(data)
183
+
184
+ for (lowcut, highcut, reduction_factor) in reduction_profile:
185
+ low = lowcut / nyquist
186
+ high = highcut / nyquist
187
+ sos = butter(2, [low, high], btype='band', output='sos')
188
+ reduced_data = reduced_data + sosfilt(sos, reduced_data) * reduction_factor
189
+
190
+ return reduced_data
191
+
192
+ def equalize_audio(data, sample_rate, lowcut, highcut):
193
+ """
194
+ Apply a bandpass filter to the audio data
195
+
196
+ Parameters:
197
+ data (numpy.ndarray): The input audio data.
198
+ sample_rate (int): The sample rate of the audio.
199
+ lowcut (float): The low cut frequency for the equalizer.
200
+ highcut (float): The high cut frequency for the equalizer.
201
+
202
+ Returns:
203
+ numpy.ndarray: The equalized audio data.
204
+ """
205
+ nyquist = 0.5 * sample_rate
206
+ low = lowcut / nyquist
207
+ high = highcut / nyquist
208
+ b, a = butter(1, [low, high], btype='band')
209
+ y = lfilter(b, a, data)
210
+ return y
211
+
212
+ def apply_wiener_filter(data):
213
+ """
214
+ Apply Wiener filter to the audio data
215
+
216
+ Parameters:
217
+ data (numpy.ndarray): The input audio data.
218
+
219
+ Returns:
220
+ numpy.ndarray: The audio data after applying the Wiener filter.
221
+ """
222
+ return wiener(data)
223
+
224
+ def upscale_mp3_to_flac(input_file_path, output_file_path_processed, max_iterations=400, threshold_value=0.4, gain_factor=22.8, reduction_profile=None, lowcut=5.0, highcut=150000.0, target_bitrate_kbps=1400, output_file_path_no_processing=None, use_wiener_filter=False):
225
+ """
226
+ Main function to upscale an MP3 file to FLAC format with optional processing.
227
+
228
+ Parameters:
229
+ input_file_path (str): Path to the input MP3 file.
230
+ output_file_path_processed (str): Path to the output processed FLAC file.
231
+ max_iterations (int): Maximum number of iterations for IST.
232
+ threshold_value (float): Threshold value for IST.
233
+ gain_factor (float): Gain factor for scaling amplitude.
234
+ reduction_profile (list of tuple): Reduction profile for gain reduction.
235
+ lowcut (float): Low cut frequency for equalizer.
236
+ highcut (float): High cut frequency for equalizer.
237
+ target_bitrate_kbps (int): Target bitrate in kbps (must be between 800 and 1400).
238
+ output_file_path_no_processing (str, optional): Path to the output FLAC file without processing. Default is None.
239
+ use_wiener_filter (bool): Flag to use Wiener filter or not. Default is False.
240
+ """
241
+ if reduction_profile is None:
242
+ reduction_profile = [
243
+ (5, 140, -28.4),
244
+ (1000, 10000, 26.4),
245
+ ]
246
+
247
+ if not (800 <= target_bitrate_kbps <= 1400):
248
+ raise ValueError("FLAC bitrate out of range. Please provide a value between 800 and 1400 kbps.")
249
+
250
+ logger.info("Loading MP3 file...")
251
+ sample_rate, samples, bitrate, audio = read_mp3(input_file_path)
252
+ logger.info(f"Original MP3 bitrate: {bitrate / 1000:.2f} kbps")
253
+
254
+ samples = np.array(audio.get_array_of_samples())
255
+ if audio.channels == 2:
256
+ samples = samples.reshape((-1, 2))
257
+
258
+ target_bitrate = target_bitrate_kbps * 1000
259
+ upscale_factor = round(target_bitrate / bitrate)
260
+ logger.info(f"Upscale factor set to: {upscale_factor}")
261
+
262
+ if samples.ndim == 1:
263
+ logger.info("Mono channel detected.")
264
+ channels = samples[:, np.newaxis]
265
+ else:
266
+ logger.info("Stereo channels detected.")
267
+ channels = samples
268
+
269
+ if output_file_path_no_processing is not None:
270
+ logger.info("Upscaling channels without processing...")
271
+ upscaled_channels_no_processing = upscale_channels(channels, upscale_factor=upscale_factor, max_iter=max_iterations, threshold=threshold_value, apply_ist=False)
272
+ new_sample_rate = sample_rate * upscale_factor
273
+ write_flac(output_file_path_no_processing, new_sample_rate, upscaled_channels_no_processing)
274
+ logger.info(f"Saved upscaled (no processing) FLAC file at {output_file_path_no_processing}")
275
+
276
+ logger.info("Upscaling and processing channels...")
277
+ upscaled_channels = upscale_channels(channels, upscale_factor=upscale_factor, max_iter=max_iterations, threshold=threshold_value, apply_ist=True)
278
+
279
+ logger.info("Scaling amplitudes...")
280
+ scaled_upscaled_channels = []
281
+ for i, channel in enumerate(channels.T):
282
+ scaled_channel = scale_amplitude(channel, upscaled_channels[:, i], gain_factor=gain_factor)
283
+ scaled_upscaled_channels.append(scaled_channel)
284
+ scaled_upscaled_channels = np.column_stack(scaled_upscaled_channels)
285
+
286
+ logger.info("Applying gain reduction...")
287
+ gain_reduced_channels = []
288
+ for i in range(scaled_upscaled_channels.shape[1]):
289
+ gain_reduced_channel = apply_gain_reduction(cp.asarray(scaled_upscaled_channels[:, i]), sample_rate * upscale_factor, reduction_profile)
290
+ gain_reduced_channels.append(cp.asnumpy(gain_reduced_channel))
291
+ gain_reduced_channels = np.column_stack(gain_reduced_channels)
292
+
293
+ logger.info("Normalizing and equalizing...")
294
+ normalized_upscaled_channels = []
295
+ for i in range(gain_reduced_channels.shape[1]):
296
+ normalized_channel = normalize_signal(gain_reduced_channels[:, i])
297
+ equalized_channel = equalize_audio(normalized_channel, sample_rate * upscale_factor, lowcut, highcut)
298
+ if use_wiener_filter:
299
+ equalized_channel = apply_wiener_filter(equalized_channel)
300
+ normalized_upscaled_channels.append(equalized_channel)
301
+ normalized_upscaled_channels = np.column_stack(normalized_upscaled_channels)
302
+
303
+ new_sample_rate = sample_rate * upscale_factor
304
+ write_flac(output_file_path_processed, new_sample_rate, normalized_upscaled_channels)
305
+ logger.info(f"Saved processed FLAC file at {output_file_path_processed}")
File without changes
@@ -0,0 +1,62 @@
1
+ import unittest
2
+ import numpy as np
3
+ import os
4
+ from fat_llama.audio_fattener.feed import read_mp3, upscale_mp3_to_flac, write_flac
5
+
6
+ class TestAudioFattener(unittest.TestCase):
7
+
8
+ def setUp(self):
9
+ # Create a small example MP3 file for testing
10
+ self.test_mp3_file = 'test_input.mp3'
11
+ self.create_test_mp3(self.test_mp3_file)
12
+
13
+ def tearDown(self):
14
+ # Remove the test MP3 file and any generated FLAC files
15
+ if os.path.exists(self.test_mp3_file):
16
+ os.remove(self.test_mp3_file)
17
+ if os.path.exists('output_processed.flac'):
18
+ os.remove('output_processed.flac')
19
+ if os.path.exists('output_upscaled_no_processing.flac'):
20
+ os.remove('output_upscaled_no_processing.flac')
21
+
22
+ def create_test_mp3(self, filename):
23
+ from pydub.generators import Sine
24
+ sine_wave = Sine(440).to_audio_segment(duration=1000) # 1 second of 440 Hz sine wave
25
+ sine_wave.export(filename, format="mp3")
26
+
27
+ def test_read_mp3(self):
28
+ sample_rate, samples, bitrate, audio = read_mp3(self.test_mp3_file)
29
+ self.assertEqual(sample_rate, 44100) # Default sample rate for the generated sine wave
30
+ self.assertEqual(len(samples), 44100) # 1 second of audio at 44100 Hz
31
+ self.assertEqual(bitrate, 63999) # Bitrate of the generated MP3
32
+
33
+ def test_upscale_mp3_to_flac(self):
34
+ upscale_mp3_to_flac(
35
+ input_file_path=self.test_mp3_file,
36
+ output_file_path_processed='output_processed.flac',
37
+ max_iterations=10, # Using a smaller number for faster testing
38
+ threshold_value=0.1,
39
+ gain_factor=1.0,
40
+ reduction_profile=[
41
+ (5, 140, -0.5),
42
+ (1000, 10000, 0.5),
43
+ ],
44
+ lowcut=5.0,
45
+ highcut=22000.0,
46
+ target_bitrate_kbps=800,
47
+ output_file_path_no_processing='output_upscaled_no_processing.flac',
48
+ use_wiener_filter=False
49
+ )
50
+ self.assertTrue(os.path.exists('output_processed.flac'))
51
+ self.assertTrue(os.path.exists('output_upscaled_no_processing.flac'))
52
+
53
+ def test_write_flac(self):
54
+ sample_rate, samples, bitrate, audio = read_mp3(self.test_mp3_file)
55
+ output_file = 'test_output.flac'
56
+ write_flac(output_file, sample_rate, samples)
57
+ self.assertTrue(os.path.exists(output_file))
58
+ if os.path.exists(output_file):
59
+ os.remove(output_file)
60
+
61
+ if __name__ == '__main__':
62
+ unittest.main()
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.1
2
+ Name: fat_llama
3
+ Version: 0.1.2
4
+ Summary: A package for CUDA-based upscaling and processing audio files, using FFT to add audio frequency details after upscaling.
5
+ Home-page: https://github.com/bkraad47/fat_llama
6
+ Author: Badruddin Kamal
7
+ Author-email: bulkguy47@gmail.com
8
+ License: BSD-3-Clause
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: BSD License
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: numpy
20
+ Requires-Dist: cupy-cuda12x
21
+ Requires-Dist: pydub
22
+ Requires-Dist: soundfile
23
+ Requires-Dist: mutagen
24
+ Requires-Dist: scipy
25
+ Requires-Dist: tqdm
26
+
27
+ # fat_llama
28
+
29
+ fat_llama is a Python package for upscaling MP3 files to FLAC format using advanced audio processing techniques. It utilizes GPU-accelerated calculations to enhance audio quality by upsampling and adding missing frequencies, resulting in richer and more detailed audio.
30
+
31
+ ## Features
32
+
33
+ - Upscale MP3 files to high-quality FLAC format.
34
+ - Optional iterative soft thresholding (IST) for enhanced audio processing.
35
+ - Gain adjustment, equalization, and optional Wiener filtering.
36
+ - Supports GPU-accelerated processing with CuPy.
37
+
38
+ ## Installation
39
+
40
+ Clone the repository:
41
+
42
+ Install:
43
+ ```
44
+ pip install fat_llama-0.1.0
45
+ ```
46
+ Further need CUDA & CuPy properly installed: https://docs.cupy.dev/en/stable/install.html
47
+
48
+ Also, requires ffmpeg for windows: https://support.audacityteam.org/basics/installing-ffmpeg
49
+ ## Usage
50
+ ### Example Usage
51
+ You can run the example provided in example.py:
52
+
53
+ ```
54
+ from fat_llama.audio_fattener import upscale_mp3_to_flac
55
+
56
+ # Example call to the method
57
+ upscale_mp3_to_flac(
58
+ input_file_path='input_short.mp3',
59
+ output_file_path_processed='output_processed.flac',
60
+ max_iterations=400,
61
+ threshold_value=0.4,
62
+ gain_factor=22.8,
63
+ reduction_profile=[
64
+ (5, 140, -28.4),
65
+ (1000, 10000, 26.4),
66
+ ],
67
+ lowcut=5.0,
68
+ highcut=150000.0,
69
+ target_bitrate_kbps=1400,
70
+ output_file_path_no_processing='output_upscaled_no_processing.flac',
71
+ use_wiener_filter=False
72
+ )
73
+ ```
74
+ ### Function Parameters
75
+ input_file_path (str): Path to the input MP3 file. Mandatory.
76
+ output_file_path_processed (str): Path to the output processed FLAC file. Mandatory.
77
+ max_iterations (int): Number of iterations for IST. Default is 400.
78
+ threshold_value (float): Threshold value for IST. Default is 0.4.
79
+ gain_factor (float): Gain factor for scaling amplitude. Default is 22.8.
80
+ reduction_profile (list): Profile for gain reduction. Default is [(5, 140, -28.4), (1000, 10000, 26.4)].
81
+ lowcut (float): Low cut frequency for equalizer. Default is 5.0.
82
+ highcut (float): High cut frequency for equalizer. Default is 150000.0.
83
+ target_bitrate_kbps (int): Target bitrate in kbps. Default is 1400.
84
+ output_file_path_no_processing (str): Path to the output upscaled (no processing) FLAC file. Default is None.
85
+ use_wiener_filter (bool): Flag to use Wiener filter. Default is False.
86
+
87
+ ## Running the Example
88
+ To run the example, execute the following command:
89
+ ```
90
+ python example.py
91
+ ```
92
+ This will upscale the MP3 file specified in the example and produce two FLAC files: one with just upscaling and one with full processing.
93
+
94
+ ## Algorithm Explanation
95
+ The upscaling process involves several steps:
96
+
97
+ 1. Reading MP3 File: The MP3 file is read, and the audio samples are extracted along with the sample rate and bitrate.
98
+ 2. Calculating Upscale Factor: The upscale factor is calculated to achieve the target bitrate.
99
+ 3. Upscaling Channels: The audio channels are upscaled using an interpolation algorithm. Each sample is repeated multiple times to increase the resolution.
100
+ 4. Iterative Soft Thresholding (IST): IST is applied to enhance the audio by adding missing frequencies. This process uses FFT to transform the signal into the frequency domain, apply a threshold to keep significant frequencies, and then inverse transform back to the time domain.
101
+ 5. Scaling Amplitude: The amplitude of the upscaled audio is scaled to match the original.
102
+ 6. Applying Gain Reduction: Frequency-specific gain reduction is applied based on a given profile.
103
+ 7. Equalization: A bandpass filter is applied to the audio to equalize it.
104
+ 8. Optional Wiener Filtering: Wiener filtering is applied to reduce noise if specified.
105
+ 9. Writing FLAC File: The processed audio is written to a FLAC file.
106
+
107
+ ## Why FFT and IST?
108
+ FFT (Fast Fourier Transform) is used to transform the audio signal into the frequency domain. This allows for the identification and manipulation of specific frequency components. By applying a threshold in the frequency domain, we can keep significant frequencies and discard noise and add it to our upscaling data to add detail to upscaling frequencies.
109
+
110
+ The report titled "Fast Sparse Fourier Transformations for NMR Spectroscopy" by Badruddin Kamal, supervised by Thomas Huber and Alastair Rendall, 2015, provides a comprehensive understanding of sparse representations and their applications in signal processing. IST leverages the concepts from this report to add missing frequencies and enhance the audio quality by making it more detailed and rich. This is particularly useful in upscaling audio where some frequencies might be missing or congested.
111
+
112
+ ### Test Audio Source, ericzo - beyond link(https://soundcloud.com/ericzomusic/free-electro-trap-anthem-beyond)
@@ -0,0 +1,18 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ setup.py
5
+ fat_llama/__init__.py
6
+ fat_llama.egg-info/PKG-INFO
7
+ fat_llama.egg-info/SOURCES.txt
8
+ fat_llama.egg-info/dependency_links.txt
9
+ fat_llama.egg-info/entry_points.txt
10
+ fat_llama.egg-info/requires.txt
11
+ fat_llama.egg-info/top_level.txt
12
+ fat_llama/audio_fattener/__init__.py
13
+ fat_llama/audio_fattener/feed.py
14
+ fat_llama/audio_fattener/__pycache__/audio_fattener.cpython-312.pyc
15
+ fat_llama/audio_fattener/__pycache__/feed.cpython-312.pyc
16
+ fat_llama/tests/__init__.py
17
+ fat_llama/tests/test_feed.py
18
+ fat_llama/tests/__pycache__/test_feed.cpython-312.pyc
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ example = example:main
@@ -0,0 +1,7 @@
1
+ numpy
2
+ cupy-cuda12x
3
+ pydub
4
+ soundfile
5
+ mutagen
6
+ scipy
7
+ tqdm
@@ -0,0 +1 @@
1
+ fat_llama
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,42 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name='fat_llama',
5
+ version='0.1.2',
6
+ packages=find_packages(),
7
+ install_requires=[
8
+ 'numpy',
9
+ 'cupy-cuda12x',
10
+ 'pydub',
11
+ 'soundfile',
12
+ 'mutagen',
13
+ 'scipy',
14
+ 'tqdm',
15
+ ],
16
+ package_data={
17
+ # Include any package data files here
18
+ 'fat_llama': ['audio_fattener/*.py', 'tests/*.py'],
19
+ },
20
+ entry_points={
21
+ 'console_scripts': [
22
+ 'example=example:main',
23
+ ],
24
+ },
25
+ author='Badruddin Kamal',
26
+ author_email='bulkguy47@gmail.com',
27
+ description='A package for CUDA-based upscaling and processing audio files, using FFT to add audio frequency details after upscaling.',
28
+ long_description=open('README.md').read(),
29
+ long_description_content_type='text/markdown',
30
+ url='https://github.com/bkraad47/fat_llama',
31
+ classifiers=[
32
+ 'Development Status :: 3 - Alpha',
33
+ 'Intended Audience :: Developers',
34
+ 'License :: OSI Approved :: BSD License',
35
+ 'Programming Language :: Python :: 3.8',
36
+ 'Programming Language :: Python :: 3.9',
37
+ 'Programming Language :: Python :: 3.10',
38
+ 'Programming Language :: Python :: 3.11',
39
+ 'Programming Language :: Python :: 3.12',
40
+ ],
41
+ license='BSD-3-Clause',
42
+ )