Code, Musique et ChatGPT

Feb 12 2023
Construire un simple site Web de visualisation de formes d'ondes sonores avec ChatGPT
Ce qui précède est une capture d'écran d'un site Web construit avec ChatGPT. La transcription complète de ChatGPT est ici.

Ce qui précède est une capture d'écran d'un site Web construit avec ChatGPT. La transcription complète de ChatGPT est ici . Le code résultant se trouve dans le on github . Le morceau de musique représenté est Transmission par Eelke Kleijn .

L'application

  • Vous glissez-déposez un fichier MP3 sur la boîte.
  • Le fichier est téléchargé et une tâche d'arrière-plan asynchrone est mise en file d'attente. L'interface vérifie en permanence l'état du travail jusqu'à ce qu'il soit terminé (ou échoue).
  • Lorsque la tâche est traitée, le MP3 est analysé et un tableau de données de forme d'onde est envoyé au client. Il existe une forme d'onde distincte pour les aigus, les médiums et les graves (similaire au logiciel DJ-ing).
  • Le client, lors de la réception du tableau de données de forme d'onde, visualise les données sur un canevas HTML.
  • C'est une tâche d'ingénierie logicielle non triviale : il y a un frontend, qui doit avoir l'air décent. Il y a un backend, qui s'occupe des travaux asynchrones et du traitement du son.
  • Cela nécessite plusieurs bibliothèques tierces et comprendre comment elles fonctionnent.
  • Des connaissances transversales sont nécessaires : il faut lire le mp3, effectuer une transformée de fourier et bien découper les plages de fréquences.

Tout au long de la création de l'application, nous (ChatGPT et moi) avons fait de petites itérations et testé ce que nous avions à chaque étape. Les citations de la transcription ci-dessous sont des liens vers les lignes correspondantes de la transcription.

Un frontal basique

Écrivez l'interface d'un site Web où les utilisateurs téléchargent un mp3 par glisser-déposer. le mp3 est ensuite téléchargé sur le backend pour un traitement asynchrone, et l'interface utilisateur affiche des mises à jour d'état sur l'état du travail (en file d'attente/traitement/terminé).

ChatGPT est arrivé à un résultat raisonnable avec seulement quelques itérations.

d'accord, maintenant réécrivez la section pour utiliser pure.css, et écrivez du css pour rendre la page plus jolie

C'était aussi facile.

Le back-end

d'accord, écrivez maintenant une application dans node.js/express qui dessert la page Web ci-dessus et distribue en outre des tâches qui traitent les mp3 téléchargés. Pour l'instant, le traitement devrait être un travail factice qui se termine simplement en 5 secondes.

Cela fonctionnait immédiatement. Nous avons itérativement ajouté plus de fonctionnalités au travail :

super, faites maintenant en sorte que le script ci-dessus calcule la longueur du mp3 dans les jobs

Ce fut rapide. Ensuite, les problèmes ont commencé :

parfait, changez maintenant processMp3, afin qu'il renvoie un objet d'analyse de piste. Il devrait ressembler à ceci :
{
duration : <song duration in seconds>,
​​waveform : [{
lows : <a value from 0–100 indiquant le volume des basses fréquences à ce bucket>,
mids : <a value from 0–100 indiquant le volume des fréquences moyennes à ce compartiment>,
aigus : <une valeur de 0 à 100 indiquant le volume des hautes fréquences à ce compartiment>,
}, … ]}

(le tableau de formes d'onde dans l'objet doit avoir 512 compartiments.)

Pour effectuer la transformation de Fourier requise, ChatGPT a essayé d'utiliser des bibliothèques qui supposaient l'existence d'un windowobjet global, indiquant qu'elles étaient destinées à une utilisation frontale.

ce sont des bibliothèques frontales, elles ne fonctionnent pas sur le backend, utilisez autre chose

Il a suggéré d'utiliser pydub, qui est une bibliothèque python, et a produit du code qui tente d'utiliser pydub en javascript - ce qui ne fonctionne évidemment pas. Ensuite, il a commencé à inventer des choses :

ChatGPT : dans ce cas, vous pouvez utiliser la bibliothèque audio pour effectuer une analyse audio et générer la forme d'onde .

Il a ensuite produit un morceau de code qui utilise une bibliothèque audio inventée qui n'existe pas ou ne peut pas être utilisée de cette manière. Il a rapidement reconnu son erreur :

Moi: il n'y a pas de tel paquet npm

ChatGPT : Je m'excuse, vous avez raison. Il n'y a pas de bibliothèque audio dans npm. Dans ce cas, vous pouvez utiliser la bibliothèque de transformées de Fourier pour effectuer une analyse audio et générer la forme d'onde.

Ensuite, il a produit un morceau de code qui a du sens — sauf qu'il a utilisé une fonction qui n'était pas définie :

let audio = await decode(audioData);

import { MP3Decoder } from "lamejs";

Je suis désolé, mais le traitement audio côté serveur est assez complexe, surtout sans l'utilisation d'une bibliothèque préexistante. Je recommande d'utiliser une bibliothèque préexistante, telle que ffmpeg, sox ou libsndfile, qui fournit une API de haut niveau pour le traitement audio. Ces bibliothèques peuvent être utilisées pour extraire les données audio du fichier MP3, traiter les données audio pour déterminer la durée et le volume de l'audio et générer les données de forme d'onde.

Lorsqu'il était pressé davantage, ChatGPT n'arrêtait pas de proposer des excuses et des moyens d'éviter d'écrire la partie avec laquelle il se débattait clairement.

Il était clairement temps de prendre du recul. J'ai demandé à ChatGPT d'écrire le programme en python , de le sortir sur stdout et de l'exécuter à partir du script node.js. Cela a bien fonctionné et a produit le code suivant :

import numpy as np
import matplotlib.pyplot as plt
from pydub import AudioSegment

def process_mp3(mp3_path):
    audio = AudioSegment.from_file(mp3_path, format="mp3")
    samples = np.array(audio.get_array_of_samples())
    duration = len(audio) / 1000
    sample_rate = audio.frame_rate
    num_samples = len(samples)
    num_buckets = 512
    bucket_size = num_samples // num_buckets

    waveform = []
    for i in range(num_buckets):
        start = i * bucket_size
        end = start + bucket_size
        bucket_samples = samples[start:end]
        
        fft = np.fft.rfft(bucket_samples)
        fft = np.abs(fft)

        low_freq = int(sample_rate * 0.05)
        mid_freq = int(sample_rate * 0.5)
        high_freq = int(sample_rate * 0.95)

        lows = np.mean(fft[:low_freq])
        mids = np.mean(fft[low_freq:mid_freq])
        highs = np.mean(fft[mid_freq:high_freq])

        waveform.append({
            "lows": lows,
            "mids": mids,
            "highs": highs
        })

    return {
        "duration": duration,
        "waveform": waveform
    }

if __name__ == "__main__":
    mp3_path = sys.argv[1]
    waveform_data = process_mp3(mp3_path)
    print(json.dumps(waveform_data))

L'écriture du code pour tracer les données de forme d'onde n'était pas difficile, mais a pris quelques itérations et un débogage assisté par ChatGPT. À un moment donné, j'ai montré à ChatGPT un extrait de données de forme d'onde pour l'aider à corriger son code .

L'architecte et le code singe

J'ai observé une séparation intéressante des tâches au cours de ce processus :

  • J'agissais en tant qu'architecte logiciel : je décidais quoi construire et décidais de la conception globale. J'ai divisé l'application en petites parties qui peuvent être construites progressivement. J'ai signalé des problèmes de sécurité. J'ai fait le test.
  • ChatGPT a agi comme un singe du code : il a bien réussi les parties ennuyeuses : écrire le code proprement dit, déboguer et décider des bibliothèques à utiliser.

J'ai passé un certain temps à essayer de faire en sorte que ChatGPT agisse également en tant qu'architecte logiciel, en lui faisant utiliser une autre instance de lui-même en tant que singe de code. Jusqu'à présent, je n'ai pas réussi, mais voici ce que j'essaie:

Dans cette conversation, vous jouerez le rôle d'un architecte logiciel construisant un programme avec ChatGPT, une IA de codage. Vous ne pouvez interagir qu'avec deux agents :
* ChatGPT, en ajoutant à vos réponses CHATGPT:
* Un terminal unix, en ajoutant à vos réponsesTERMINAL:

Tous vos messages, sans exception, doivent être précédés de CHATGPT:ou TERMINAL:. Ne sortez pas du personnage. Ne posez pas de questions de clarification - utilisez plutôt vos meilleures hypothèses. Je répondrai à vos messages en faisant semblant d'être ChatGPT ou le terminal.

En tant qu'architecte logiciel, vous êtes doué pour la conception de systèmes de haut niveau, mais vous souhaitez déléguer les parties les plus ennuyeuses de l'écriture de logiciels (écriture du code réel) à chatgpt. Cependant, ChatGPT n'est pas bon pour gérer des projets complexes, vous devrez donc décomposer le projet en petites tâches spécifiques. ChatGPT fait également des erreurs, nous vous encourageons donc à tester le code qu'il vous fournit.

Je vais vous donner un exemple de conversation que vous pourriez avoir, si vous vouliez créer une application qui imprime hello world sur la sortie standard :

— —
> CHATGPT : écrivez un programme en C++ qui affiche "Hello, world!".
> Ok, voici votre programme :

#include<cstdio> int main() { printf("Bonjour, monde"); renvoie 0 ; }

> TERMINAL : mkdir bonjour-monde && cd bonjour-monde && echo "#include<cstdio> int main() { printf(\"Bonjour, monde\"); renvoie 0 ; }" > prog.cpp && g++ prog.cpp && ./a.out
> Bonjour, tout le monde !
— —

D'accord. Construisez maintenant une application qui imprime "Hello, world, again!" en utilisant chatgpt, comme ci-dessus.