diff --git a/app/audio/AudioForm.tsx b/app/audio/AudioForm.tsx index b108208..badb680 100644 --- a/app/audio/AudioForm.tsx +++ b/app/audio/AudioForm.tsx @@ -45,7 +45,6 @@ export default function AudioForm({ // Set Tempo async function submitForm() { try { - console.log("submitting form"); // Get File if YT Link let file = audioForm.audio_file; if (audioForm.audio_link && !file) { @@ -58,7 +57,6 @@ export default function AudioForm({ // This shouldn't happen throw new Error("No audio file provided"); } - console.log("audio retrieved: ", file.name); // Get Tempo let tempo = 120; @@ -66,7 +64,7 @@ export default function AudioForm({ tempo = await getTempo(file); setAudioForm({ ...audioForm, tempo }); } else tempo = audioForm.tempo; - console.log("tempo: ", tempo); + // console.log("tempo: ", tempo); songName.current = file.name.split(".")[0]; // Create Form Data diff --git a/app/audio/ExportView.tsx b/app/audio/ExportView.tsx index e07f631..50241bd 100644 --- a/app/audio/ExportView.tsx +++ b/app/audio/ExportView.tsx @@ -11,163 +11,181 @@ import { AudioStorage, Stem } from "@/utils/types"; import { Download, Undo } from "lucide-react"; import { zipAllParts } from "@/utils/zipAll"; -const ExportView = forwardRef((_props, ref) => { - const { audioStorage, audioForm, songName, songKey, finalMidiFile } = - useContext(AudioContext); +const ExportView = forwardRef( + ({ showSheetMusic = true }, ref) => { + const { audioStorage, audioForm, songName, songKey, finalMidiFile } = + useContext(AudioContext); - return ( -
-
- -
+ {showSheetMusic ? ( +
+ ) : ( +
+

+ Sheet music viewer unavailable. Please try again at the start of + the next hour. +

+
+ )} + - - - Export - - -
    - -
  1. Final Score Midi
  2. - { - const midiBlob = new Blob([finalMidiFile.current!], { - type: "audio/midi", - }); - const url = URL.createObjectURL(midiBlob); - const a = document.createElement("a"); - a.href = url; - a.download = `${songName.current}.mid`; - a.click(); - URL.revokeObjectURL(url); - }} - /> -
    - {audioForm.audio_link && ( +
    + + + Export + + +
      -
    1. Original Audio
    2. +
    3. Final Score Midi
    4. { - const url = URL.createObjectURL(audioForm.audio_file!); + const midiBlob = new Blob([finalMidiFile.current!], { + type: "audio/midi", + }); + const url = URL.createObjectURL(midiBlob); const a = document.createElement("a"); a.href = url; - a.download = `${songName.current}.mp3`; + a.download = `${songName.current}.mid`; a.click(); URL.revokeObjectURL(url); }} />
      - )} - -
    5. Midi and Audio for Each Instrument
    6. - zipAllParts(audioStorage!, songName.current)} - /> -
      -
      -
    7. - {songKey.current}, {audioForm.tempo} BPM -
    8. -
    -
    -
    - - - Midi Files - - -
      - {Object.entries( - audioStorage as Record, - ).map(([key, stem]) => { - if (!stem.midiBlob) return; - - let name = key.split("_").join(" "); - name = name.replace(/\b\w/g, (char) => char.toUpperCase()); - - return ( - -
    1. {name}
    2. + {audioForm.audio_link && ( + +
    3. Original Audio
    4. { - const url = URL.createObjectURL(stem.midiBlob!); + const url = URL.createObjectURL( + audioForm.audio_file!, + ); const a = document.createElement("a"); a.href = url; - a.download = `${stem.name}.mid`; + a.download = `${songName.current}.mp3`; a.click(); URL.revokeObjectURL(url); }} />
      - ); - })} -
    -
    -
    - - - Audio Files - - -
      - {Object.entries( - audioStorage as Record, - ).map(([key, stem]) => { - if (!stem.audioBlob) return; + )} + +
    1. Midi and Audio for Each Instrument
    2. + + zipAllParts(audioStorage!, songName.current) + } + /> +
      +
      +
    3. + {songKey.current}, {audioForm.tempo} BPM +
    4. +
    +
    +
    + + + Midi Files + + +
      + {Object.entries( + audioStorage as Record, + ).map(([key, stem]) => { + if (!stem.midiBlob) return; - let name = key.split("_").join(" "); - name = name.replace(/\b\w/g, (char) => char.toUpperCase()); + let name = key.split("_").join(" "); + name = name.replace(/\b\w/g, (char) => char.toUpperCase()); - return ( - -
    1. {name}
    2. - { - const url = URL.createObjectURL(stem.audioBlob!); - const a = document.createElement("a"); - a.href = url; - a.download = `${stem.name}.mp3`; - a.click(); - URL.revokeObjectURL(url); - }} - /> -
      - ); - })} -
    -
    -
    - (window.location.href = "/audio")} - className="button-primary flex h-min w-full cursor-pointer items-center justify-center gap-2 rounded-3xl px-6 py-2 text-base shadow-md transition-colors xl:max-w-[300px]" - > - Convert Again - -
    - -
- ); -}); + return ( + +
  • {name}
  • + { + const url = URL.createObjectURL(stem.midiBlob!); + const a = document.createElement("a"); + a.href = url; + a.download = `${stem.name}.mid`; + a.click(); + URL.revokeObjectURL(url); + }} + /> +
    + ); + })} + + + + + + Audio Files + + +
      + {Object.entries( + audioStorage as Record, + ).map(([key, stem]) => { + if (!stem.audioBlob) return; + + let name = key.split("_").join(" "); + name = name.replace(/\b\w/g, (char) => char.toUpperCase()); + + return ( + +
    1. {name}
    2. + { + const url = URL.createObjectURL(stem.audioBlob!); + const a = document.createElement("a"); + a.href = url; + a.download = `${stem.name}.mp3`; + a.click(); + URL.revokeObjectURL(url); + }} + /> +
      + ); + })} +
    +
    +
    + (window.location.href = "/audio")} + className="button-primary flex h-min w-full cursor-pointer items-center justify-center gap-2 rounded-3xl px-6 py-2 text-base shadow-md transition-colors xl:max-w-[300px]" + > + Convert Again + +
    +
    +
    + ); + }, +); export default ExportView; diff --git a/app/audio/MidiEditor.tsx b/app/audio/MidiEditor.tsx index 335858f..d01a11c 100644 --- a/app/audio/MidiEditor.tsx +++ b/app/audio/MidiEditor.tsx @@ -33,11 +33,12 @@ interface Props { conversionFlag: Dispatch>; isMidiComplete: boolean; setFlatScore: Dispatch>; + setShowSheetMusic: Dispatch>; } const MidiEditor = forwardRef( ( - { conversionFlag, isMidiComplete, setFlatScore }: Props, + { conversionFlag, isMidiComplete, setFlatScore, setShowSheetMusic }: Props, ref: React.ForwardedRef, ) => { const { @@ -124,7 +125,6 @@ const MidiEditor = forwardRef( const maxIndex = parseInt(formData.get("maximum_frequency") as string); const maxFreq = frequencies[maxIndex]; if (maxFreq < 13000) { - console.log("maxFreq", maxFreq); adjustments.maximum_frequency = maxFreq.toString(); } @@ -132,7 +132,6 @@ const MidiEditor = forwardRef( const minIndex = parseInt(formData.get("minimum_frequency") as string); const minFreq = frequencies[minIndex]; if (minFreq > 0) { - console.log("minFreq", minFreq); adjustments.minimum_frequency = minFreq.toString(); } @@ -168,7 +167,6 @@ const MidiEditor = forwardRef( try { const names = Object.keys(audioStorage); - const midiFiles = await Promise.all( Object.entries(audioStorage as Record).map( async ([_, stem]) => { @@ -189,24 +187,24 @@ const MidiEditor = forwardRef( const blob = new Blob([finalMidiFile.current], { type: "application/octet-stream", }); - console.log("creating flat score..."); - const response = await createScore(blob, songName.current); - setFlatScore(response.id); - // **For Testing: Download the merged MIDI file** - // const url = URL.createObjectURL(blob); - // const a = document.createElement("a"); - // a.href = url; - // a.download = "TranscribedSong.mid"; - // a.click(); - // URL.revokeObjectURL(url); - } catch (error: any) { - if (error.message === "402") { - message.current = - "Score limit reached. Please try again at the start of the next hour."; - } else { - message.current = "Failed to merge midi files."; + try { + const response = await createScore(blob, songName.current); + setFlatScore(response.id); + setShowSheetMusic(true); + } catch (error: any) { + if (error.message === "402") { + message.current = + "Score limit reached. Please try again at the start of the next hour."; + setShowSheetMusic(false); + // Still set flatScore to trigger transition, but with a dummy value + setFlatScore("error-402"); + } else { + throw error; + } } + } catch (error: any) { + message.current = "Failed to merge midi files."; console.error(message.current); } finally { setIsSubmitting(false); diff --git a/app/audio/page.tsx b/app/audio/page.tsx index 6a8fff1..d699942 100644 --- a/app/audio/page.tsx +++ b/app/audio/page.tsx @@ -15,6 +15,7 @@ export default function Page() { const [isConverting, setIsConverting] = useState(false); const [isMidiComplete, setIsMidiComplete] = useState(false); const [isEditingComplete, setIsEditingComplete] = useState(false); + const [showSheetMusic, setShowSheetMusic] = useState(true); const flatRef = useRef(null); const editorRef = useRef(null); @@ -40,7 +41,9 @@ export default function Page() { const container = flatRef.current; if (!container || !flatScore) return; - console.log("Creating Flat.io embed"); + // Don't try to create embed for error state + if (flatScore === "error-402") return; + import("flat-embed") .then(({ default: Embed }) => { new Embed(container, { @@ -91,6 +94,7 @@ export default function Page() { conversionFlag={setIsConverting} isMidiComplete={isMidiComplete} setFlatScore={setFlatScore} + setShowSheetMusic={setShowSheetMusic} /> - +
    ); diff --git a/package-lock.json b/package-lock.json index 025b6b8..fa0f79f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "songscribe", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 26dbc7c..8422538 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "songscribe", - "version": "1.1.0", + "version": "1.2.0", "author": "Gabriel Serna", "private": true, "scripts": { diff --git a/utils/flat.ts b/utils/flat.ts index 97db58b..951c10b 100644 --- a/utils/flat.ts +++ b/utils/flat.ts @@ -16,7 +16,6 @@ export async function createScore(midiFile: Blob, title: string) { dataEncoding: "base64", }), }).catch((error) => { - console.log(error); if (error.message.includes("402")) { throw new Error("402"); } else throw new Error("0"); diff --git a/utils/getAudioFromUrl.ts b/utils/getAudioFromUrl.ts index e2c083c..64832bc 100644 --- a/utils/getAudioFromUrl.ts +++ b/utils/getAudioFromUrl.ts @@ -16,7 +16,6 @@ export default async function getAudioFromURL( error.message.includes("Failed to fetch") || error.message.includes("ERR_CONNECTION_REFUSED") ) { - console.log("Error: Failed to Fetch"); throw new Error(error.message); } }); @@ -31,6 +30,5 @@ export default async function getAudioFromURL( const file = new File([blob], "youtube_audio.mp3", { type: blob.type }); setAudioForm((prev) => ({ ...prev, audio_file: file })); - console.log("YT audio retrieved successfully"); return file; } diff --git a/utils/infoList.ts b/utils/infoList.ts index 106cd51..cf10a74 100644 --- a/utils/infoList.ts +++ b/utils/infoList.ts @@ -4,7 +4,7 @@ export const infoList = [ "If the tempo was not able to be detected properly, it will default to 120 BPM.", "Hey, I hope you're having a great day. Thank you so much for taking the time to check out my project! ^_^", "If there are any unnecessarily high or low notes in the MIDI, you can adjust the min and max frequencies and regenerate it.", - "If you want the MIDI output to be more like static chords, try increasing the minimum note length and note segmentation, and decrease the confidence threshold.", + "If you want the MIDI output to be more like static chords, increase the minimum note length and note segmentation and decrease the confidence threshold.", "The backdoor dominant is the five chord in the relative major of the parallel minor.", "If you want to remove the MIDI transcription for an instrument that isn't part of the song, set the confidence threshold all the way up and regenerate it.", "To continue working on the transcription, you can download the MIDI file and upload it to your music notation editor of choice.", diff --git a/utils/isolateAudio.ts b/utils/isolateAudio.ts index 4a18552..8f5bf0d 100644 --- a/utils/isolateAudio.ts +++ b/utils/isolateAudio.ts @@ -21,7 +21,6 @@ export default async function isolateAudio( error.message.includes("Failed to fetch") || error.message.includes("ERR_CONNECTION_REFUSED") ) { - console.log("Error: Failed to Fetch"); throw new Error(error.message); } }); @@ -46,7 +45,6 @@ export default async function isolateAudio( }); }); }); - console.log("Audio isolated successfully"); } async function alignSingle() { @@ -62,7 +60,6 @@ export default async function isolateAudio( error.message.includes("Failed to fetch") || error.message.includes("ERR_CONNECTION_REFUSED") ) { - console.log("failed to fetch error"); throw new Error(error.message); } }); @@ -81,7 +78,5 @@ export default async function isolateAudio( no_vocals: { name: "no_vocals", audioBlob: blob, midiBlob: null }, }) as AudioStorage, ); - - console.log("Audio aligned successfully"); } }