Показать сообщение отдельно
Старый 14.09.2025, 21:17   #13
Дмитрий
Администратор
 
Аватар для Дмитрий
 
Турниров выиграно: 1

Регистрация: 12.12.2008
Адрес: Москва прошлого тысячелетия.
Сообщений: 209,554
Сказал(а) спасибо: 45,509
Поблагодарили 272,172 раз(а) в 102,736 сообщениях
Дмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспоримаДмитрий репутация неоспорима
По умолчанию

Цитата:
Сообщение от Дмитрий Посмотреть сообщение
Нейросеть (если нужен сложный анализ):
Используется CNN (например, с tensorflow или pytorch) для классификации аудиофрагментов на "пауза" и "трек".

Python-скрипт с CNN

Скрипт обучает CNN на TensorFlow для классификации пауз/треков, анализирует WAV с librosa и генерирует CUE с метаданными из Discogs. Пауза исключена для первых треков сторон.

Код:
python

import librosa
import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv1D, Dense, Flatten
import discogs_client

# 1. Подготовка данных (пример, замените на наш датасет)
def prepare_dataset(wav_files, cue_files):
    X, y = [], []
    for wav_file, cue_file in zip(wav_files, cue_files):
        y_audio, sr = librosa.load(wav_file)
        # Чтение таймингов из CUE
        with open(cue_file, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            timings = []
            for line in lines:
                if 'INDEX 01' in line:
                    time_str = line.strip().split()[-1]
                    mm, ss, ff = map(int, time_str.split(':'))
                    timings.append(mm * 60 + ss + ff / 75)
        
        # Разбиение на 1-секундные фрагменты
        for i in range(0, len(y_audio) - sr, sr):
            fragment = y_audio[i:i + sr]
            is_pause = any(abs(t - i / sr) < 1 for t in timings)  # Пауза, если близко к таймингу
            X.append(fragment)
            y.append(0 if is_pause else 1)
    
    X = np.array(X).reshape(-1, sr, 1)
    y = np.array(y)
    return X, y

# 2. Создание и обучение CNN
def train_cnn(X_train, y_train):
    model = Sequential([
        Conv1D(32, kernel_size=3, activation='relu', input_shape=(44100, 1)),
        Conv1D(64, kernel_size=3, activation='relu'),
        Flatten(),
        Dense(128, activation='relu'),
        Dense(1, activation='sigmoid')
    ])
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    model.fit(X_train, y_train, epochs=10, batch_size=32, validation_split=0.2)
    return model

# 3. Генерация CUE
def create_cue(side1_wav, side2_wav, output_cue, model):
    # Discogs API
    try:
        d = discogs_client.Client('MyApp/1.0', user_token='YOUR_DISCOGS_TOKEN')  # Замените на токен
        release = d.release(249504)  # Zoolook ID
        metadata = {
            "genre": release.genres[0] if release.genres else "Electronic",
            "date": release.year,
            "comment": "ОЦИФРОВКА 20.08.25, Polydor-POLH 15, UK",
            "composer": "Denis Vanzetto, Pierre Mourey, Jean-Michel Jarre",
            "performer": release.artists[0].name,
            "title": release.title
        }
    except:
        metadata = {
            "genre": "Electronic",
            "date": "1984",
            "comment": "ОЦИФРОВКА 20.08.25, Polydor-POLH 15, UK",
            "composer": "Denis Vanzetto, Pierre Mourey, Jean-Michel Jarre",
            "performer": "Jean-Michel Jarre",
            "title": "Zoolook"
        }

    # Анализ пауз
    def get_timings(wav_file, track_count, model):
        y, sr = librosa.load(wav_file)
        timings = [0]  # Первый трек начинается с 0
        for i in range(0, len(y) - sr, sr):
            fragment = y[i:i + sr].reshape(1, sr, 1)
            pred = model.predict(fragment)[0][0]
            if pred < 0.5:  # Пауза
                timings.append(i / sr)
        return timings[:track_count]

    # Треки
    track_list_side1 = [("Ethnicolor", None), ("Diva", None)]
    track_list_side2 = [("Zoolook", None), ("Wooloomooloo", None), ("Zoolookologie", None),
                        ("Blah-Blah-Cafe", None), ("Ethnicolor II", None)]

    # Тайминги
    timings_side1 = get_timings(side1_wav, len(track_list_side1), model)
    timings_side2 = get_timings(side2_wav, len(track_list_side2), model)
    track_list_side1 = [(title, time) for (title, _), time in zip(track_list_side1, timings_side1)]
    track_list_side2 = [(title, time) for (title, _), time in zip(track_list_side2, timings_side2)]

    with open(output_cue, 'w', encoding='utf-8') as f:
        f.write(f'REM GENRE {metadata["genre"]}\n')
        f.write(f'REM DATE {metadata["date"]}\n')
        f.write(f'REM COMMENT "{metadata["comment"]}"\n')
        f.write(f'REM COMPOSER "{metadata["composer"]}"\n')
        f.write(f'PERFORMER "{metadata["performer"]}"\n')
        f.write(f'TITLE "{metadata["title"]}"\n')

        f.write(f'FILE "{os.path.basename(side1_wav)}" WAVE\n')
        for i, (title, time) in enumerate(track_list_side1, 1):
            mm = int(time // 60)
            ss = int(time % 60)
            f.write(f'  TRACK {i:02d} AUDIO\n')
            f.write(f'    TITLE "{title}"\n')
            f.write(f'    PERFORMER "{metadata["performer"]}"\n')
            f.write(f'    INDEX 01 {mm:02d}:{ss:02d}:00\n')

        f.write(f'FILE "{os.path.basename(side2_wav)}" WAVE\n')
        for i, (title, time) in enumerate(track_list_side2, len(track_list_side1) + 1):
            mm = int(time // 60)
            ss = int(time % 60)
            f.write(f'  TRACK {i:02d} AUDIO\n')
            f.write(f'    TITLE "{title}"\n')
            f.write(f'    PERFORMER "{metadata["performer"]}"\n')
            if i > len(track_list_side1) + 2:  # Пауза для треков 5–7
                gap_time = time - 2
                gap_mm = int(gap_time // 60)
                gap_ss = int(gap_time % 60)
                f.write(f'    INDEX 00 {gap_mm:02d}:{gap_ss:02d}:00\n')
            f.write(f'    INDEX 01 {mm:02d}:{ss:02d}:00\n')

# Пример обучения (замените на ваш датасет)
wav_files = ["path/to/wav1.wav", "path/to/wav2.wav"]  # Ваш датасет
cue_files = ["path/to/cue1.cue", "path/to/cue2.cue"]
X_train, y_train = prepare_dataset(wav_files, cue_files)
model = train_cnn(X_train, y_train)
model.save("pause_detector.h5")  # Сохранить модель

# Генерация CUE
create_cue("1 СТОРОНА.wav", "2 СТОРОНА.wav", "zoolook.cue", model)
__________________
О нас думают плохо лишь те, кто хуже нас. А те, кто лучше нас, им просто не до нас.
--Омар Хайям

Обновления по запросу — на Я.Ди. «Мэйл-облако» для тех, кто помогает нашему интернет-проекту, и для тех, кто хотел бы это делать, но пока не знает, как.

Помогая форуму ВТО, вы прежде всего помогаете себе! А не делаете что-то абстрактное для «других», совершенно незнакомых и безразличных вам людей.
Дмитрий вне форума   Ответить с цитированием