НИЧЕГО НЕ ПИШИТЕ ПОКА НЕ СКАЖУ!!!: import json
import random
import pandas as pd
from collections import Counter
from music21 import converter, note, chord, stream, tempo, instrument, analysis
from transformers import pipeline
 
# Предопределенный словарь эмоций и ассоциированных сцен
emotion_to_scene = {
    'joyful': ['веселье', 'сценарий праздника', 'танцевальная сцена'],
    'sad': ['потеря', 'грустная сцена', 'размышления'],
    'tense': ['опасная ситуация', 'погоня', 'конфликт'],
    'peaceful': ['умиротворение', 'спокойствие', 'отдых']
}
 
# Используем pipeline из трансформеров для анализа эмоций
emotion_analysis_pipeline = pipeline('sentiment-analysis')
 
# Расширенная база данных жанров, стилей и инструментов
genre_database = pd.DataFrame({
    'instrument': ['Piano', 'Violin', 'Flute', 'Trumpet', 'Guitar', 'Bass Guitar', 'Drums', 'Synthesizer', 'Saxophone'],
    'genre': ['Classical', 'Classical', 'Classical', 'Jazz', 'Rock', 'Rock', 'Rock', 'Electronic', 'Jazz'],
    'style': ['Romantic', 'Baroque', 'Modern', 'Swing', 'Heavy Metal', 'Funk', 'Pop Rock', 'House', 'Smooth Jazz']
})
 
# Пример баз данных композиторов (упрощенный)
composer_database = pd.DataFrame({
    'composer': ['Ludwig van Beethoven', 'Johann Sebastian Bach', 'Wolfgang Amadeus Mozart', 'Frederic Chopin', 'Antonio Vivaldi'],
    'epoch': ['Classical', 'Baroque', 'Classical', 'Romantic', 'Baroque'],
    'nationality': ['German', 'German', 'Austrian', 'Polish', 'Italian']
})
 
def analyze_emotion(element_info):
    """
    Расширенный анализ эмоций с учетом темпа, динамики и артикуляций.
    """
    key_signature = element_info['key_signature']
    dynamics = element_info['dynamics']
    metronome_mark = element_info['metronome_mark']
    articulations = element_info['articulations']
    
    if key_signature and 'minor' in key_signature:
        emotion = 'sad'
    elif dynamics and dynamics > 0.7:
        emotion = 'joyful'
    else:
        emotion = 'peaceful'
    
    if metronome_mark:
        if metronome_mark > 120:
            emotion = 'joyful' if emotion == 'peaceful' else 'tense'
    
    if articulations and any(articulation in ['staccato', 'accent'] for articulation in articulations):
        emotion = 'tense' if emotion == 'sad' else 'joyful'
 
    return emotion
 
def extract_harmony(chord_element):
    """
    Анализируем аккорд и возвращаем его гармоническую функцию.
    """
    root = chord_element.root()
    if chord_element.isDominantSeventh():
        return f"Dominant Seventh ({root})"
    elif chord_element.isDiminishedSeventh():
        return f"Diminished Seventh ({root})"
    elif chord_element.isMajorTriad():
        return f"Major Triad ({root})"
    elif chord_element.isMinorTriad():
        return f"Minor Triad ({root})"
    else:
        return f"Chord ({root})"
 
def get_genre_style(instrument_name):
    """
    Извлечение жанра и стиля на основе инструмента.
    """
    record = genre_database[genre_database['instrument'].str.contains(instrument_name, case=False, na=False)]
    if not record.empty:
        return record.iloc[0]['genre'], record.iloc[0]['style']
    else:
        return 'Unknown', 'Unknown'
 
def get_composer_info(composer_name):
    """
    Извлечение информации о композиторе.
    """
    record = composer_database[composer_database['composer'].str.contains(composer_name, case=False, na=False)]
    if not record.empty:
        return record.iloc[0]['epoch'], record.iloc[0]['nationality']
    else:
        return 'Unknown', 'Unknown'
 
def extract_notes_and_chords(file_path):
    """
    Основная функция для извлечения нот и аккордов из партитуры, а также связанной информации.
    """
    score = converter.parse(file_path)
    elements = []
    scenes = []
    emotion_counts = Counter()
    
    # Определение басовых линий
    bass_parts = [part for part in score.parts if 'bass' in part.id.lower() or 'bass' in part.partName.lower()]
 
    for part_index, part in enumerate(score.parts):
        part_instrument = part.getInstrument()
        part_name = part_instrument.partName if part_instrument else f"Part {part_index + 1}"
        genre, style = get_genre_style(part_name)
 
        measure_number = 1
        for measure in part.getElementsByClass(stream.Measure):
            time_signature = measure.timeSignature
            key_signature = measure.keySignature
            tempo_marks = measure.metronomeMarkBoundaries()
            metronome_mark = tempo_marks[0][2].number if tempo_marks else None
 
            for element in measure.notesAndRests:
                element_info = {
                    'part_index': part_index + 1,
                    'instrument': part_name,
                    'genre': genre,
                    'style': style,
                    'type': '',
                    'pitch': '',
                    'duration': element.duration.quarterLength,
                    'offset': element.offset,
                    'measure': measure_number,
                    'time_signature': str(time_signature) if time_signature else None,
                    'key_signature': str(key_signature) if key_signature else None,
                    'dynamics': None,
                    'articulations': [str(art) for art in element.articulations],
                    'harmony': None,
                    'is_bass': part in bass_parts,
                    'metronome_mark': metronome_mark
                }
                
                if not element.isRest:
                    if hasattr(element, 'volume') and element.volume.velocity is not None:
                        dynamics = element.volume.velocity / 127.0
                        element_info['dynamics'] = dynamics
                    
                    if isinstance(element, note.Note):
                        element_info['type'] = 'note'
                        element_info['pitch'] = str(element.pitch)
                    elif isinstance(element, chord.Chord):
                        element_info['type'] = 'chord'
                        element_info['pitch'] = '+'.join(str(p) for p in element.pitches)
                        element_info['harmony'] = extract_harmony(element)
                
                    # Добавляем отладочное сообщение после извлечения информации об элементе
                    print(f"Extracted element information: {element_info}")
                    
                    # Определение эмоции
                    emotion = analyze_emotion(element_info)
                    element_info['emotion'] = emotion
                    elements.append(element_info)
                    
                    possible_scenes = emotion_to_scene.get(emotion, [])
                    scene_description = random.choice(possible_scenes) if possible_scenes else 'Scene not defined'
                    scene_with_details = f"Instrument: {element_info['instrument']}, Genre: {element_info['genre']}, Style: {element_info['style']}, Type: {element_info['type']}, Harmony: {element_info['harmony']}, Scene: {scene_description}"
                    scenes.append((measure_number, emotion, scene_with_details))
                    emotion_counts[emotion] += 1  
 
            measure_number += 1
    
    scene_descriptions = generate_scene_descriptions(elements)
    return elements, scenes, emotion_counts, scene_descriptions
 
def generate_scene_descriptions(elements):
    """
    Пример функции генерации описаний сцен на основе информации из элементов.
    """
    scene_descriptions = []
    for element in elements:
        scene_descriptions.append(f"Scene for Measure {element['measure']}: Emotion - {element['emotion']}")
    return scene_descriptions
 
def generate_text_summary(elements, scenes):
    """
    Генерация текстового описания музыкальной композиции.
    """
    summary = []
    
    for element in elements:
        text = f"Measure: {element['measure']}, Instrument: {element['instrument']}, Genre: {element['genre']}, Style: {element['style']}, "
        text += f"Type: {element['type']}, Pitch: {element['pitch']}, Duration: {element['duration']}, Dynamics: {element['dynamics']}, "
        text += f"Articulations: {', '.join(element['articulations'])}, Harmony: {element['harmony']}, Emotion: {element['emotion']}"
        summary.append(text)
        
    summary.append("\nScene Descriptions:\n")
    for measure_number, emotion, scene_description in scenes:
        summary.append(f"Measure: {measure_number}, Emotion: {emotion}, Scene Description: {scene_description}")
        
    return "\n".join(summary)
 
# Пример использования функции
elements, scenes, emotion_counts, scene_descriptions = extract_notes_and_chords('C:/Users/ARTYOM/Documents/Python/Bring_it_up.musicxml')
summary = generate_text_summary(elements, scenes)
 
print(summary)