lvthn-codec 1.0.0__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.
- lvthn_codec-1.0.0/LICENSE +21 -0
- lvthn_codec-1.0.0/PATENTS +30 -0
- lvthn_codec-1.0.0/PKG-INFO +136 -0
- lvthn_codec-1.0.0/README.EN.md +109 -0
- lvthn_codec-1.0.0/README.md +109 -0
- lvthn_codec-1.0.0/codec.py +149 -0
- lvthn_codec-1.0.0/core/__init__.py +0 -0
- lvthn_codec-1.0.0/core/audio.py +330 -0
- lvthn_codec-1.0.0/core/container.py +25 -0
- lvthn_codec-1.0.0/core/image.py +267 -0
- lvthn_codec-1.0.0/lvthn_codec.egg-info/PKG-INFO +136 -0
- lvthn_codec-1.0.0/lvthn_codec.egg-info/SOURCES.txt +15 -0
- lvthn_codec-1.0.0/lvthn_codec.egg-info/dependency_links.txt +1 -0
- lvthn_codec-1.0.0/lvthn_codec.egg-info/requires.txt +5 -0
- lvthn_codec-1.0.0/lvthn_codec.egg-info/top_level.txt +2 -0
- lvthn_codec-1.0.0/pyproject.toml +46 -0
- lvthn_codec-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 FreshLend Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
LVTHN-CODEC — Patent Notice
|
|
2
|
+
|
|
3
|
+
This software is released under the MIT License.
|
|
4
|
+
|
|
5
|
+
The author is not aware of any patents that cover the algorithms implemented
|
|
6
|
+
here. The core techniques used are:
|
|
7
|
+
|
|
8
|
+
Audio:
|
|
9
|
+
- MDCT / IMDCT with sine window (Princen-Bradley, 1986–87; expired)
|
|
10
|
+
- TDAC (Time-Domain Aliasing Cancellation, 1986; expired)
|
|
11
|
+
- Mid/Side stereo coding (Blumlein, 1930s; classic technique)
|
|
12
|
+
- Bark-scale band partitioning (Barkhausen 1960s, public domain)
|
|
13
|
+
- Absolute Threshold of Hearing (Terhardt 1979, public domain)
|
|
14
|
+
- Rice coding (Golomb 1966, Rice 1979; expired)
|
|
15
|
+
- Adaptive per-band quantization (basic idea, expired)
|
|
16
|
+
|
|
17
|
+
Images:
|
|
18
|
+
- Oklab color space (Björn Ottosson, 2020; public domain)
|
|
19
|
+
- Block DCT (discrete cosine transform; expired)
|
|
20
|
+
- Run-Length Encoding (RLE; public domain)
|
|
21
|
+
- Zstandard compression (Yann Collet, 2015; BSD/GPLv2, patent-free)
|
|
22
|
+
|
|
23
|
+
This is NOT a legal guarantee of patent non-infringement. No warranty is
|
|
24
|
+
provided. If you distribute binaries based on this code commercially,
|
|
25
|
+
consult a patent attorney about your jurisdiction.
|
|
26
|
+
|
|
27
|
+
The author has intentionally avoided:
|
|
28
|
+
- Full psychoacoustic masking models identical to MP3/AAC
|
|
29
|
+
- SBR / PS / HE-AAC extensions
|
|
30
|
+
- Any code from FFmpeg, LAME, Opus, Vorbis, or other existing codecs
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lvthn-codec
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Universal LVTHN media codec: audio (MDCT + Bark + Psy) and images (Oklab + DCT + zstd)
|
|
5
|
+
Author: FreshGame
|
|
6
|
+
Maintainer: FreshLend Studio
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: audio,codec,image,compression,mdct,dct,psychoacoustics,oklab,lvn,patent-free
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
16
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
License-File: PATENTS
|
|
21
|
+
Requires-Dist: numpy==2.2.6
|
|
22
|
+
Requires-Dist: scipy==1.15.3
|
|
23
|
+
Requires-Dist: numba==0.68.1
|
|
24
|
+
Requires-Dist: zstandard==0.25.0
|
|
25
|
+
Requires-Dist: Pillow==12.3.0
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# LVTHN-CODEC [RU](README.md) | **EN**
|
|
29
|
+
|
|
30
|
+
A modular, patent-clean, and highly efficient media codec written in Python.
|
|
31
|
+
It uses a universal container (`.lvn`) that supports both **Audio** and **Images**, applying modern psychoacoustic and psychovisual models to outperform industry standards like MP3 and PNG.
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
* **Universal container (`.lvn`):** One format for everything. The decoder automatically detects what is inside.
|
|
36
|
+
* **Audio codec:** MDCT + Mid/Side stereo + Bark scale bands + Absolute Threshold of Hearing (ATH) + Adaptive quantization.
|
|
37
|
+
* **Image codec:** Oklab color space + Block DCT + RLE + Zstandard.
|
|
38
|
+
* **Performance:**
|
|
39
|
+
* Audio outperforms MP3 in size by **~15%** at the same perceived quality.
|
|
40
|
+
* Images outperform PNG in size by **6 to 7 times** with visually indistinguishable quality.
|
|
41
|
+
* High speed: Audio RTF < 0.02, 4K image decoding takes about 3 seconds.
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
Ensure you have Python 3.10+ installed.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install numpy scipy numba zstandard Pillow sounddevice PySide6
|
|
49
|
+
```
|
|
50
|
+
*(Note: For `converter.py` to work with formats like MP3 or JPG, you need to install `ffmpeg` and add it to the system PATH environment variable).*
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### 1. Codec CLI (`codec.py`)
|
|
55
|
+
Direct encoding and decoding to and from the `.lvn` format.
|
|
56
|
+
```bash
|
|
57
|
+
# Audio
|
|
58
|
+
python codec.py encode track.wav track.lvn compact
|
|
59
|
+
python codec.py decode track.lvn out.wav
|
|
60
|
+
|
|
61
|
+
# Images
|
|
62
|
+
python codec.py encode-img image.png image.lvn fast
|
|
63
|
+
python codec.py decode-img image.lvn out.png
|
|
64
|
+
|
|
65
|
+
# File info
|
|
66
|
+
python codec.py info track.lvn
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. Converter (`converter.py`)
|
|
70
|
+
Converts any supported format (via ffmpeg) to `.lvn` and back.
|
|
71
|
+
```bash
|
|
72
|
+
python converter.py to-lvn track.mp3 track.lvn --profile default
|
|
73
|
+
python converter.py from-lvn track.lvn track_out.mp3 --bitrate 192k
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3. Player (`player.py`)
|
|
77
|
+
Modern GUI player and image viewer based on PySide6.
|
|
78
|
+
```bash
|
|
79
|
+
python player.py track.lvn
|
|
80
|
+
python player.py image.lvn
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. Benchmark (`benchmark.py`)
|
|
84
|
+
Testing speed and compression ratio on your files.
|
|
85
|
+
```bash
|
|
86
|
+
python benchmark.py --audio audio.wav --image image.png --image-profiles fast max
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Profiles
|
|
90
|
+
|
|
91
|
+
### Audio Profiles
|
|
92
|
+
| Profile | Description | SNR | Best for |
|
|
93
|
+
|---|---|---|---|
|
|
94
|
+
| `compact` | Maximum compression | 20.0 | Everyday listening, saving space |
|
|
95
|
+
| `default` | Balanced | 24.0 | High-quality music |
|
|
96
|
+
| `speech` | Voice optimized | 20.0 | Podcasts, audiobooks |
|
|
97
|
+
| `detail` | Preserves quiet details | 24.0 | Lo-Fi, acoustic, vinyl |
|
|
98
|
+
| `master` | Archival quality | 30.0 | Mastering, studio archives |
|
|
99
|
+
|
|
100
|
+
### Image Profiles
|
|
101
|
+
| Profile | Quality | Zstd Level | Best for |
|
|
102
|
+
|---|---|---|---|
|
|
103
|
+
| `fast` | 85 | 1 | Quick preview, game textures |
|
|
104
|
+
| `default` | 92 | 12 | Web images, everyday use |
|
|
105
|
+
| `max` | 98 | 19 | Archiving, professional photography |
|
|
106
|
+
|
|
107
|
+
## Benchmarks
|
|
108
|
+
|
|
109
|
+
### Audio (179 sec track)
|
|
110
|
+
| File | Profile | Bitrate | SNR | Enc RTF | Dec RTF | Compression |
|
|
111
|
+
|---|---|---|---|---|---|---|
|
|
112
|
+
| acoustic.wav | compact | 113 kbps | 27.5 dB | 0.022 | 0.009 | 13.5x |
|
|
113
|
+
| acoustic.wav | master | 225 kbps | 40.8 dB | 0.020 | 0.010 | 6.8x |
|
|
114
|
+
|
|
115
|
+
### Images (4K 8.29 MP)
|
|
116
|
+
| File | Profile | PSNR | Enc Time | Dec Time | Compression |
|
|
117
|
+
|---|---|---|---|---|---|
|
|
118
|
+
| 4k_image.png | fast | 42.1 dB | 4.10s | 3.14s | 7.1x |
|
|
119
|
+
| 4k_image.png | max | 48.3 dB | 29.32s | 3.14s | 4.3x |
|
|
120
|
+
|
|
121
|
+
*(PSNR > 40 dB is considered visually indistinguishable from the original. RTF < 1.0 means faster than real time).*
|
|
122
|
+
|
|
123
|
+
## Architecture
|
|
124
|
+
|
|
125
|
+
* `codec.py` - Main CLI and API.
|
|
126
|
+
* `core/container.py` - Universal LVTHN wrapper.
|
|
127
|
+
* `core/audio.py` - Audio math (MDCT, Bark, Psy).
|
|
128
|
+
* `core/image.py` - Image math (Oklab, DCT).
|
|
129
|
+
* `player.py` - GUI (PySide6).
|
|
130
|
+
* `converter.py` - FFmpeg wrapper.
|
|
131
|
+
* `benchmark.py` - Performance testing tool.
|
|
132
|
+
|
|
133
|
+
## License and Patents
|
|
134
|
+
|
|
135
|
+
The project is distributed under the **MIT** license.
|
|
136
|
+
It is built exclusively on patent-free algorithms (MDCT, Oklab, DCT, Rice coding, Zstandard). See the `PATENTS` file for a detailed breakdown.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# LVTHN-CODEC [RU](README.md) | **EN**
|
|
2
|
+
|
|
3
|
+
A modular, patent-clean, and highly efficient media codec written in Python.
|
|
4
|
+
It uses a universal container (`.lvn`) that supports both **Audio** and **Images**, applying modern psychoacoustic and psychovisual models to outperform industry standards like MP3 and PNG.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
* **Universal container (`.lvn`):** One format for everything. The decoder automatically detects what is inside.
|
|
9
|
+
* **Audio codec:** MDCT + Mid/Side stereo + Bark scale bands + Absolute Threshold of Hearing (ATH) + Adaptive quantization.
|
|
10
|
+
* **Image codec:** Oklab color space + Block DCT + RLE + Zstandard.
|
|
11
|
+
* **Performance:**
|
|
12
|
+
* Audio outperforms MP3 in size by **~15%** at the same perceived quality.
|
|
13
|
+
* Images outperform PNG in size by **6 to 7 times** with visually indistinguishable quality.
|
|
14
|
+
* High speed: Audio RTF < 0.02, 4K image decoding takes about 3 seconds.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Ensure you have Python 3.10+ installed.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install numpy scipy numba zstandard Pillow sounddevice PySide6
|
|
22
|
+
```
|
|
23
|
+
*(Note: For `converter.py` to work with formats like MP3 or JPG, you need to install `ffmpeg` and add it to the system PATH environment variable).*
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### 1. Codec CLI (`codec.py`)
|
|
28
|
+
Direct encoding and decoding to and from the `.lvn` format.
|
|
29
|
+
```bash
|
|
30
|
+
# Audio
|
|
31
|
+
python codec.py encode track.wav track.lvn compact
|
|
32
|
+
python codec.py decode track.lvn out.wav
|
|
33
|
+
|
|
34
|
+
# Images
|
|
35
|
+
python codec.py encode-img image.png image.lvn fast
|
|
36
|
+
python codec.py decode-img image.lvn out.png
|
|
37
|
+
|
|
38
|
+
# File info
|
|
39
|
+
python codec.py info track.lvn
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Converter (`converter.py`)
|
|
43
|
+
Converts any supported format (via ffmpeg) to `.lvn` and back.
|
|
44
|
+
```bash
|
|
45
|
+
python converter.py to-lvn track.mp3 track.lvn --profile default
|
|
46
|
+
python converter.py from-lvn track.lvn track_out.mp3 --bitrate 192k
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 3. Player (`player.py`)
|
|
50
|
+
Modern GUI player and image viewer based on PySide6.
|
|
51
|
+
```bash
|
|
52
|
+
python player.py track.lvn
|
|
53
|
+
python player.py image.lvn
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 4. Benchmark (`benchmark.py`)
|
|
57
|
+
Testing speed and compression ratio on your files.
|
|
58
|
+
```bash
|
|
59
|
+
python benchmark.py --audio audio.wav --image image.png --image-profiles fast max
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Profiles
|
|
63
|
+
|
|
64
|
+
### Audio Profiles
|
|
65
|
+
| Profile | Description | SNR | Best for |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| `compact` | Maximum compression | 20.0 | Everyday listening, saving space |
|
|
68
|
+
| `default` | Balanced | 24.0 | High-quality music |
|
|
69
|
+
| `speech` | Voice optimized | 20.0 | Podcasts, audiobooks |
|
|
70
|
+
| `detail` | Preserves quiet details | 24.0 | Lo-Fi, acoustic, vinyl |
|
|
71
|
+
| `master` | Archival quality | 30.0 | Mastering, studio archives |
|
|
72
|
+
|
|
73
|
+
### Image Profiles
|
|
74
|
+
| Profile | Quality | Zstd Level | Best for |
|
|
75
|
+
|---|---|---|---|
|
|
76
|
+
| `fast` | 85 | 1 | Quick preview, game textures |
|
|
77
|
+
| `default` | 92 | 12 | Web images, everyday use |
|
|
78
|
+
| `max` | 98 | 19 | Archiving, professional photography |
|
|
79
|
+
|
|
80
|
+
## Benchmarks
|
|
81
|
+
|
|
82
|
+
### Audio (179 sec track)
|
|
83
|
+
| File | Profile | Bitrate | SNR | Enc RTF | Dec RTF | Compression |
|
|
84
|
+
|---|---|---|---|---|---|---|
|
|
85
|
+
| acoustic.wav | compact | 113 kbps | 27.5 dB | 0.022 | 0.009 | 13.5x |
|
|
86
|
+
| acoustic.wav | master | 225 kbps | 40.8 dB | 0.020 | 0.010 | 6.8x |
|
|
87
|
+
|
|
88
|
+
### Images (4K 8.29 MP)
|
|
89
|
+
| File | Profile | PSNR | Enc Time | Dec Time | Compression |
|
|
90
|
+
|---|---|---|---|---|---|
|
|
91
|
+
| 4k_image.png | fast | 42.1 dB | 4.10s | 3.14s | 7.1x |
|
|
92
|
+
| 4k_image.png | max | 48.3 dB | 29.32s | 3.14s | 4.3x |
|
|
93
|
+
|
|
94
|
+
*(PSNR > 40 dB is considered visually indistinguishable from the original. RTF < 1.0 means faster than real time).*
|
|
95
|
+
|
|
96
|
+
## Architecture
|
|
97
|
+
|
|
98
|
+
* `codec.py` - Main CLI and API.
|
|
99
|
+
* `core/container.py` - Universal LVTHN wrapper.
|
|
100
|
+
* `core/audio.py` - Audio math (MDCT, Bark, Psy).
|
|
101
|
+
* `core/image.py` - Image math (Oklab, DCT).
|
|
102
|
+
* `player.py` - GUI (PySide6).
|
|
103
|
+
* `converter.py` - FFmpeg wrapper.
|
|
104
|
+
* `benchmark.py` - Performance testing tool.
|
|
105
|
+
|
|
106
|
+
## License and Patents
|
|
107
|
+
|
|
108
|
+
The project is distributed under the **MIT** license.
|
|
109
|
+
It is built exclusively on patent-free algorithms (MDCT, Oklab, DCT, Rice coding, Zstandard). See the `PATENTS` file for a detailed breakdown.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# LVTHN-CODEC **RU** | [EN](README.EN.md)
|
|
2
|
+
|
|
3
|
+
Модульный, патентно-чистый и высокоэффективный медиа-кодек, написанный на Python.
|
|
4
|
+
Он использует универсальный контейнер (`.lvn`), который поддерживает как **Аудио**, так и **Изображения**, применяя современные психоакустические и психовизуальные модели, чтобы превзойти промышленные стандарты вроде MP3 и PNG.
|
|
5
|
+
|
|
6
|
+
## Особенности
|
|
7
|
+
|
|
8
|
+
* **Универсальный контейнер (`.lvn`):** Один формат для всего. Декодер автоматически определяет, что внутри.
|
|
9
|
+
* **Аудиокодек:** MDCT + Mid/Side стерео + полосы Барка + Абсолютный порог слышимости (ATH) + Адаптивное квантование.
|
|
10
|
+
* **Кодек изображений:** Цветовое пространство Oklab + Блочный DCT + RLE + Zstandard.
|
|
11
|
+
* **Производительность:**
|
|
12
|
+
* Аудио превосходит MP3 по размеру на **~15%** при том же воспринимаемом качестве.
|
|
13
|
+
* Изображения превосходят PNG по размеру в **6-7 раз** при визуально неотличимом качестве.
|
|
14
|
+
* Высокая скорость: RTF аудио < 0.02, декодирование 4К-картинки ~3 секунды.
|
|
15
|
+
|
|
16
|
+
## Установка
|
|
17
|
+
|
|
18
|
+
Убедитесь, что у вас установлен Python 3.10+.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install numpy scipy numba zstandard Pillow sounddevice PySide6
|
|
22
|
+
```
|
|
23
|
+
*(Примечание: Для работы `converter.py` с форматами вроде MP3 или JPG необходимо установить `ffmpeg` и добавить его в системную переменную PATH).*
|
|
24
|
+
|
|
25
|
+
## Использование
|
|
26
|
+
|
|
27
|
+
### 1. CLI кодек (`codec.py`)
|
|
28
|
+
Прямое кодирование и декодирование в/из формата `.lvn`.
|
|
29
|
+
```bash
|
|
30
|
+
# Аудио
|
|
31
|
+
python codec.py encode track.wav track.lvn compact
|
|
32
|
+
python codec.py decode track.lvn out.wav
|
|
33
|
+
|
|
34
|
+
# Изображения
|
|
35
|
+
python codec.py encode-img image.png image.lvn fast
|
|
36
|
+
python codec.py decode-img image.lvn out.png
|
|
37
|
+
|
|
38
|
+
# Информация о файле
|
|
39
|
+
python codec.py info track.lvn
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Конвертер (`converter.py`)
|
|
43
|
+
Конвертирует любые поддерживаемые форматы (через ffmpeg) в `.lvn` и обратно.
|
|
44
|
+
```bash
|
|
45
|
+
python converter.py to-lvn track.mp3 track.lvn --profile default
|
|
46
|
+
python converter.py from-lvn track.lvn track_out.mp3 --bitrate 192k
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 3. Плеер (`player.py`)
|
|
50
|
+
Современный GUI-плеер и просмотрщик картинок на PySide6.
|
|
51
|
+
```bash
|
|
52
|
+
python player.py track.lvn
|
|
53
|
+
python player.py image.lvn
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 4. Бенчмарк (`benchmark.py`)
|
|
57
|
+
Тестирование скорости и степени сжатия на ваших файлах.
|
|
58
|
+
```bash
|
|
59
|
+
python benchmark.py --audio audio.wav --image image.png --image-profiles fast max
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Профили
|
|
63
|
+
|
|
64
|
+
### Профили аудио
|
|
65
|
+
| Профиль | Описание | SNR | Для чего лучше всего |
|
|
66
|
+
|---------|-------------|-----|----------|
|
|
67
|
+
| `compact` | Максимальное сжатие | 20.0 | Повседневное прослушивание, экономия места |
|
|
68
|
+
| `default` | Сбалансированный | 24.0 | Музыка высокого качества |
|
|
69
|
+
| `speech` | Оптимизация под голос | 20.0 | Подкасты, аудиокниги |
|
|
70
|
+
| `detail` | Сохраняет тихие детали | 24.0 | Lo-Fi, акустика, винил |
|
|
71
|
+
| `master` | Архивное качество | 30.0 | Мастеринг, студийные архивы |
|
|
72
|
+
|
|
73
|
+
### Профили изображений
|
|
74
|
+
| Профиль | Качество | Уровень Zstd | Для чего лучше всего |
|
|
75
|
+
|---------|---------|------------|----------|
|
|
76
|
+
| `fast` | 85 | 1 | Быстрый просмотр, текстуры для игр |
|
|
77
|
+
| `default` | 92 | 12 | Картинки для веба, повседневное использование |
|
|
78
|
+
| `max` | 98 | 19 | Архивация, профессиональная фотография |
|
|
79
|
+
|
|
80
|
+
## Бенчмарки
|
|
81
|
+
|
|
82
|
+
### Аудио (трек 179 сек)
|
|
83
|
+
| Файл | Профиль | Битрейт | SNR | Enc RTF | Dec RTF | Сжатие |
|
|
84
|
+
|---|---|---|---|---|---|---|
|
|
85
|
+
| acoustic.wav | compact | 113 kbps | 27.5 dB | 0.022 | 0.009 | 13.5x |
|
|
86
|
+
| acoustic.wav | master | 225 kbps | 40.8 dB | 0.020 | 0.010 | 6.8x |
|
|
87
|
+
|
|
88
|
+
### Изображения (4K 8.29 Мп)
|
|
89
|
+
| Файл | Профиль | PSNR | Время Enc | Время Dec | Сжатие |
|
|
90
|
+
|---|---|---|---|---|---|
|
|
91
|
+
| 4k_image.png | fast | 42.1 dB | 4.10s | 3.14s | 7.1x |
|
|
92
|
+
| 4k_image.png | max | 48.3 dB | 29.32s | 3.14s | 4.3x |
|
|
93
|
+
|
|
94
|
+
*(PSNR > 40 dB считается визуально неотличимым от оригинала. RTF < 1.0 означает работу быстрее реального времени).*
|
|
95
|
+
|
|
96
|
+
## Архитектура
|
|
97
|
+
|
|
98
|
+
* `codec.py` - Основной CLI и API.
|
|
99
|
+
* `core/container.py` - Универсальная обёртка LVTHN.
|
|
100
|
+
* `core/audio.py` - Математика аудио (MDCT, Bark, Psy).
|
|
101
|
+
* `core/image.py` - Математика изображений (Oklab, DCT).
|
|
102
|
+
* `player.py` - Графический интерфейс (PySide6).
|
|
103
|
+
* `converter.py` - Обёртка над FFmpeg.
|
|
104
|
+
* `benchmark.py` - Инструмент тестирования производительности.
|
|
105
|
+
|
|
106
|
+
## Лицензия и Патенты
|
|
107
|
+
|
|
108
|
+
Проект распространяется под лицензией **MIT**.
|
|
109
|
+
Он построен исключительно на алгоритмах, свободных от патентов (MDCT, Oklab, DCT, Rice coding, Zstandard). Подробный разбор смотрите в файле `PATENTS`.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import time
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import numpy as np
|
|
5
|
+
from scipy.io import wavfile
|
|
6
|
+
|
|
7
|
+
from core import container, audio, image
|
|
8
|
+
|
|
9
|
+
PROFILES = {
|
|
10
|
+
'default': {'delta': 0.18, 'snr': 24.0},
|
|
11
|
+
'compact': {'delta': 0.25, 'snr': 20.0},
|
|
12
|
+
'detail': {'delta': 0.05, 'snr': 24.0},
|
|
13
|
+
'speech': {'delta': 0.10, 'snr': 20.0},
|
|
14
|
+
'master': {'delta': 0.03, 'snr': 30.0},
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
IMG_PROFILES = {
|
|
18
|
+
'fast': {'quality': 85, 'level': 1},
|
|
19
|
+
'default': {'quality': 92, 'level': 12},
|
|
20
|
+
'max': {'quality': 98, 'level': 19},
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def encode_pcm(pcm, sr, ch, delta, target_snr_db):
|
|
24
|
+
payload = audio.encode_audio(pcm, sr, ch, delta, target_snr_db)
|
|
25
|
+
return container.wrap(container.MEDIA_AUDIO, payload)
|
|
26
|
+
|
|
27
|
+
def decode_lvn(data):
|
|
28
|
+
media_type, payload = container.unwrap(data)
|
|
29
|
+
if media_type == container.MEDIA_AUDIO:
|
|
30
|
+
return audio.decode_audio(payload)
|
|
31
|
+
elif media_type == container.MEDIA_IMAGE:
|
|
32
|
+
return image.decode_image(payload)
|
|
33
|
+
else:
|
|
34
|
+
raise ValueError(f'Unsupported media_type: 0x{media_type:02x}')
|
|
35
|
+
|
|
36
|
+
def decode_lvn_info(data):
|
|
37
|
+
media_type, payload = container.unwrap(data)
|
|
38
|
+
if media_type == container.MEDIA_AUDIO:
|
|
39
|
+
info = audio.get_audio_info(payload)
|
|
40
|
+
info['media_type'] = media_type
|
|
41
|
+
info['total'] = len(data)
|
|
42
|
+
return info
|
|
43
|
+
elif media_type == container.MEDIA_IMAGE:
|
|
44
|
+
info = image.get_image_info(payload)
|
|
45
|
+
info['media_type'] = media_type
|
|
46
|
+
info['total'] = len(data)
|
|
47
|
+
return info
|
|
48
|
+
return dict(media_type=media_type, total=len(data))
|
|
49
|
+
|
|
50
|
+
def read_wav(path):
|
|
51
|
+
sr, d = wavfile.read(path)
|
|
52
|
+
if d.dtype == np.int16: d = d.astype(np.float64) / 32768.0
|
|
53
|
+
elif d.dtype == np.int32: d = d.astype(np.float64) / 2147483648.0
|
|
54
|
+
elif d.dtype == np.uint8: d = (d.astype(np.float64) - 128.0) / 128.0
|
|
55
|
+
else: d = d.astype(np.float64)
|
|
56
|
+
if d.ndim == 1: d = d[:, None]
|
|
57
|
+
return d, sr
|
|
58
|
+
|
|
59
|
+
def write_wav(path, pcm, sr):
|
|
60
|
+
wavfile.write(path, sr, np.clip(pcm * 32767, -32768, 32767).astype(np.int16))
|
|
61
|
+
|
|
62
|
+
def read_image(path):
|
|
63
|
+
from PIL import Image
|
|
64
|
+
img = Image.open(path)
|
|
65
|
+
if img.mode == 'RGBA':
|
|
66
|
+
return np.array(img), 4
|
|
67
|
+
else:
|
|
68
|
+
return np.array(img.convert('RGB')), 3
|
|
69
|
+
|
|
70
|
+
def write_image(path, pixels, channels):
|
|
71
|
+
from PIL import Image
|
|
72
|
+
img = Image.fromarray(pixels)
|
|
73
|
+
img.save(path)
|
|
74
|
+
|
|
75
|
+
def main():
|
|
76
|
+
if len(sys.argv) < 2:
|
|
77
|
+
print('LVTHN-CODEC')
|
|
78
|
+
print('Commands: encode | decode | info | encode-img | decode-img | profiles')
|
|
79
|
+
sys.exit(1)
|
|
80
|
+
cmd, args = sys.argv[1], sys.argv[2:]
|
|
81
|
+
|
|
82
|
+
if cmd == 'encode':
|
|
83
|
+
if len(args) < 2: sys.exit('usage: encode in.wav out.lvn [profile|delta] [target_snr_db]')
|
|
84
|
+
pcm, sr = read_wav(args[0])
|
|
85
|
+
arg2 = args[2] if len(args) > 2 else 'default'
|
|
86
|
+
if arg2 in PROFILES:
|
|
87
|
+
delta = PROFILES[arg2]['delta']
|
|
88
|
+
tsnr = PROFILES[arg2]['snr']
|
|
89
|
+
print(f'[audio profile: {arg2}] delta={delta} snr={tsnr}')
|
|
90
|
+
else:
|
|
91
|
+
delta = float(arg2)
|
|
92
|
+
tsnr = float(args[3]) if len(args) > 3 else 24.0
|
|
93
|
+
|
|
94
|
+
t0 = time.time()
|
|
95
|
+
data = encode_pcm(pcm, sr, pcm.shape[1], delta, target_snr_db=tsnr)
|
|
96
|
+
Path(args[1]).write_bytes(data)
|
|
97
|
+
print(f'OK {args[1]} {len(data)} bytes ({pcm.size * 2 / len(data):.2f}x vs PCM) encode={time.time() - t0:.2f}s')
|
|
98
|
+
|
|
99
|
+
elif cmd == 'decode':
|
|
100
|
+
if len(args) < 2: sys.exit('usage: decode in.lvn out.wav')
|
|
101
|
+
pcm, sr, ch, n = decode_lvn(Path(args[0]).read_bytes())
|
|
102
|
+
write_wav(args[1], pcm, sr)
|
|
103
|
+
print(f'OK {args[1]} {n} samples, {ch} ch, {sr} Hz')
|
|
104
|
+
|
|
105
|
+
elif cmd == 'encode-img':
|
|
106
|
+
if len(args) < 2: sys.exit('usage: encode-img in.png out.lvn [profile|quality] [level]')
|
|
107
|
+
pixels, ch = read_image(args[0])
|
|
108
|
+
arg2 = args[2] if len(args) > 2 else 'default'
|
|
109
|
+
if arg2 in IMG_PROFILES:
|
|
110
|
+
q = IMG_PROFILES[arg2]['quality']
|
|
111
|
+
lvl = IMG_PROFILES[arg2]['level']
|
|
112
|
+
print(f'[image profile: {arg2}] quality={q} level={lvl}')
|
|
113
|
+
else:
|
|
114
|
+
q = int(arg2)
|
|
115
|
+
lvl = int(args[3]) if len(args) > 3 else 19
|
|
116
|
+
|
|
117
|
+
t0 = time.time()
|
|
118
|
+
payload = image.encode_image(pixels, pixels.shape[1], pixels.shape[0], ch, q, lvl)
|
|
119
|
+
data = container.wrap(container.MEDIA_IMAGE, payload)
|
|
120
|
+
Path(args[1]).write_bytes(data)
|
|
121
|
+
print(f'OK {args[1]} {len(data)} bytes encode={time.time() - t0:.2f}s')
|
|
122
|
+
|
|
123
|
+
elif cmd == 'decode-img':
|
|
124
|
+
if len(args) < 2: sys.exit('usage: decode-img in.lvn out.png')
|
|
125
|
+
mt, payload = container.unwrap(Path(args[0]).read_bytes())
|
|
126
|
+
if mt != container.MEDIA_IMAGE: sys.exit('Not an image')
|
|
127
|
+
pixels = image.decode_image(payload)
|
|
128
|
+
write_image(args[1], pixels, pixels.shape[2] if len(pixels.shape) > 2 else 1)
|
|
129
|
+
print(f'OK {args[1]}')
|
|
130
|
+
|
|
131
|
+
elif cmd == 'info':
|
|
132
|
+
if not args: sys.exit('usage: info file.lvn')
|
|
133
|
+
info = decode_lvn_info(Path(args[0]).read_bytes())
|
|
134
|
+
if info['media_type'] == container.MEDIA_AUDIO:
|
|
135
|
+
print(f"LVTHN v1 audio {info['sr']} Hz {info['ch']} ch {info['n_samples'] / info['sr']:.2f}s delta={info['delta']:.4f}")
|
|
136
|
+
print(f" target_snr_db: {info['target_snr_db']:.1f} use_ms: {info['use_ms']} total: {info['total']}")
|
|
137
|
+
elif info['media_type'] == container.MEDIA_IMAGE:
|
|
138
|
+
print(f"LVTHN v1 image {info['width']}x{info['height']} alpha={info['has_alpha']} quality={info['quality']:.0f} total: {info['total']}")
|
|
139
|
+
|
|
140
|
+
elif cmd == 'profiles':
|
|
141
|
+
print('Audio profiles:')
|
|
142
|
+
for name, p in PROFILES.items():
|
|
143
|
+
print(f' {name:10s} delta={p["delta"]:<6} snr={p["snr"]}')
|
|
144
|
+
print('Image profiles:')
|
|
145
|
+
for name, p in IMG_PROFILES.items():
|
|
146
|
+
print(f' {name:10s} quality={p["quality"]:<4} level={p["level"]}')
|
|
147
|
+
|
|
148
|
+
if __name__ == '__main__':
|
|
149
|
+
main()
|
|
File without changes
|