File size: 3,540 Bytes
af8e0fa
 
 
b12171d
af8e0fa
 
 
d14d2b9
 
af8e0fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
00b2148
b12171d
 
 
 
 
 
00b2148
 
b12171d
 
af8e0fa
 
 
 
 
 
 
 
 
 
 
 
 
3ea06c2
9a36366
00b2148
a07d0b1
b12171d
af8e0fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b12171d
 
 
a07d0b1
af8e0fa
 
b12171d
 
 
 
af8e0fa
 
b12171d
af8e0fa
 
 
 
 
 
b12171d
af8e0fa
 
 
 
b12171d
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import gradio as gr
import os
import allin1
import zipfile

from pathlib import Path

from dissector import generate_dissector_data

HEADER = """
<header style="text-align: center;">
  <h1>
    All-In-One Music Structure Analyzer 🔮
  </h1>
  <p>
    <a href="https://github.com/mir-aidj/all-in-one">[Python Package]</a>
    <a href="https://arxiv.org/abs/2307.16425">[Paper]</a>
    <a href="https://taejun.kim/music-dissector/">[Visual Demo]</a>
  </p>
</header>
<main
  style="display: flex; justify-content: center;"
>
  <div
    style="display: inline-block;"
  >
    <p>
      This Space demonstrates the music structure analyzer predicts:
      <ul
        style="padding-left: 1rem;"
      >
        <li>BPM</li>
        <li>Beats</li>
        <li>Downbeats</li>
        <li>Functional segment boundaries</li>
        <li>Functional segment labels (e.g. intro, verse, chorus, bridge, outro)</li>
      </ul>
    </p>
    <p>
      It takes about 4:30 to analyze a 3-minute song.
      If you are in a hurry, you can <strong><u>try the examples at the bottom</u></strong>.
    </p>
    <p>
      For more information, please visit the links above ✨🧸
    </p>
  </div>
</main>
"""

CACHE_EXAMPLES = os.getenv('CACHE_EXAMPLES', '1') == '1'

def compress_files(folder_path, dissector_file, original_audio):
    """Compresses files in the specified folder into a .zip file"""
    zip_path = folder_path + ".zip"
    with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, _, files in os.walk(folder_path):
            for file in files:
                zipf.write(os.path.join(root, file), arcname=file)
        zipf.write(dissector_file, arcname='dissector.json')  # Fixed the name
        zipf.write(original_audio, arcname='mixdown.mp3')  # Added original audio
    return zip_path

def analyze(path):
  path = Path(path)
  result = allin1.analyze(
    path,
    multiprocess=False,
    keep_byproducts=True,  # TODO: remove this
  )

  fig = allin1.visualize(result)
  fig.set_dpi(300)

  allin1.sonify(result, out_dir='./sonif')
  sonif_path = Path(f'./sonif/{path.stem}.sonif{path.suffix}').resolve().as_posix()
      
  dissector_file = generate_dissector_data(path.stem, result)  
  compressed_file = compress_files(f"demix/htdemucs/{path.stem}", dissector_file, path.as_posix())

  return result.bpm, fig, sonif_path, compressed_file


with gr.Blocks() as demo:
  gr.HTML(HEADER)

  input_audio_path = gr.Audio(
    label='Input',
    source='upload',
    type='filepath',
    format='mp3',
    show_download_button=False,
  )
  button = gr.Button('Analyze', variant='primary')
  output_viz = gr.Plot(label='Visualization')
  with gr.Row():
    output_bpm = gr.Textbox(label='BPM', scale=1)
    output_sonif = gr.Audio(
      label='Sonification',
      type='filepath',
      format='mp3',
      show_download_button=False,
      scale=9,
    )
    output_compressed = gr.File(
        label="Compressed Files",
        type="file",
    )
  gr.Examples(
    examples=[
        './assets/kult.mp3',
        # './assets/krematorii.mp3',
      # './assets/NewJeans - Super Shy.mp3',
      # './assets/Bruno Mars - 24k Magic.mp3'
    ],
    inputs=input_audio_path,
    outputs=[output_bpm, output_viz, output_sonif, output_compressed],
    fn=analyze,
    cache_examples=CACHE_EXAMPLES,
  )
  button.click(
    fn=analyze,
    inputs=input_audio_path,
    outputs=[output_bpm, output_viz, output_sonif, output_compressed],
    api_name='analyze',
  )

if __name__ == '__main__':
  demo.launch()