File size: 3,683 Bytes
e0171fd
 
b054a29
24d2316
e0171fd
24d2316
e0171fd
 
 
 
 
 
 
 
bd23bae
 
 
 
 
c14d215
bd23bae
 
 
 
c14d215
bd23bae
 
fa2e050
 
 
 
6b49f37
 
bd23bae
6b49f37
fa2e050
bd23bae
6b49f37
 
bd23bae
6b49f37
bd23bae
c14d215
 
24d2316
6b49f37
 
b054a29
bd23bae
 
 
 
 
b054a29
 
 
c14d215
 
 
b054a29
c14d215
 
6b49f37
bd23bae
b054a29
bd23bae
6b49f37
 
c14d215
bd23bae
6b49f37
 
 
 
b054a29
 
e14c302
 
bd23bae
 
 
 
 
 
e0171fd
bd23bae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e0171fd
bd23bae
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import pronouncing
import string
import itertools
import gradio as gr

CONSONANTS = set(string.ascii_uppercase) - set('AEIOU')

def get_phones(word):
    phones_for_word = pronouncing.phones_for_word(word)
    if not phones_for_word:
        return None
    phones = phones_for_word[0].split()
    return phones

def _get_rhyming_tail(phones):
    """
    Automatically detect the syllable count based on vowel sounds,
    then return the appropriate rhyming tail.
    """
    vowels = [phone for phone in phones if phone[0] in 'AEIOU']
    syllable_count = len(vowels)
    if syllable_count < 1:
        return None
    return phones[-syllable_count * 2:]  # Use the detected syllable count to get rhyming tail

def get_exact_rhymes(phones):
    rhyming_tail = _get_rhyming_tail(phones)
    if not rhyming_tail:
        return []
    
    rhyming_tail_str = " ".join(rhyming_tail)
    matches = pronouncing.search(rhyming_tail_str + "$")
    
    exact_rhymes = [match for match in matches if rhyming_tail == _get_rhyming_tail(get_phones(match))]
    return exact_rhymes

def get_filtered_loose_rhymes(phones):
    """
    Fallback function to find words with a similar ending sound by allowing slight variations.
    Applies additional filtering to avoid unrelated results.
    """
    rhyming_tail = _get_rhyming_tail(phones)
    if not rhyming_tail:
        return []
    
    search_pattern = " ".join(phone[:-1] + "." for phone in rhyming_tail)
    matches = pronouncing.search(search_pattern)

    # Filter matches to ensure they closely resemble the original word's rhyme structure
    filtered_rhymes = [match for match in matches if match != phones]
    return filtered_rhymes

def find_rhymes_for_phrase(phrase):
    words = phrase.split()
    rhyming_options = []

    for word in words:
        phones = get_phones(word)
        if phones is None:
            rhyming_options.append([f"{word} (Not recognized)"])
            continue
        
        # Try to find exact rhymes first
        exact_rhymes = get_exact_rhymes(phones)
        
        # If no exact rhymes are found, fallback to filtered loose rhymes
        if exact_rhymes:
            rhyming_options.append(exact_rhymes)
        else:
            loose_rhymes = get_filtered_loose_rhymes(phones)
            if loose_rhymes:
                rhyming_options.append(loose_rhymes)
            else:
                rhyming_options.append([f"{word} (No rhymes found)"])
    
    combined_results = list(itertools.product(*rhyming_options))
    unique_results = set(" ".join(combination) for combination in combined_results)
    
    # Return a list of unique rhyming combinations
    return list(unique_results)

# Function to update the notepad with a selected rhyme
def add_to_notepad(notepad, selected_rhyme):
    return notepad + " " + selected_rhyme

# Gradio Interface
with gr.Blocks() as demo:
    gr.Markdown("## Interactive Rhyming Generator with Notepad")
    
    # Inputs for the rhyming generator
    phrase_input = gr.Textbox(label="Enter phrase (space-separated words)")
    
    # Output areas
    rhyme_output = gr.Dataframe(headers=["Rhyming Phrases"], interactive=False)
    notepad = gr.Textbox(label="Notepad", lines=10, placeholder="Write your lyrics here...")
    
    # Button for generating rhymes
    generate_btn = gr.Button("Generate Rhymes")
    
    # Functionality to select a rhyme and add it to the notepad
    rhyme_output.change(add_to_notepad, inputs=[notepad, rhyme_output], outputs=notepad)
    
    # Display rhyming results and update notepad on button click
    generate_btn.click(find_rhymes_for_phrase, inputs=[phrase_input], outputs=rhyme_output)

demo.launch()