Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/DMG_README.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
═══════════════════════════════════════════════════════════
HeartMuLa Studio for macOS
CTFN Studio for macOS
═══════════════════════════════════════════════════════════

Thank you for downloading HeartMuLa Studio!
Thank you for downloading CTFN Studio!

🎵 INSTALLATION
───────────────────────────────────────────────────────────

1. Drag "HeartMuLa.app" to the "Applications" folder
1. Drag "CTFN Studio.app" to the "Applications" folder
2. Double-click the app to launch
3. On first launch:
- macOS may show a security warning
Expand Down Expand Up @@ -42,7 +42,7 @@ Logs are stored in:
🎸 METAL GPU ACCELERATION
───────────────────────────────────────────────────────────

HeartMuLa Studio is optimized for Apple Metal GPUs:
CTFN Studio is optimized for Apple Metal GPUs:
• Apple Silicon: Native acceleration with Metal Performance Shaders
• Intel Macs: Metal support for compatible GPUs

Expand All @@ -55,7 +55,7 @@ HeartMuLa Studio is optimized for Apple Metal GPUs:
✓ Reference audio style transfer (experimental)
✓ AI-generated lyrics
✓ Queue system for multiple generations
Professional Spotify-inspired interface
Modern interface

📚 DOCUMENTATION
───────────────────────────────────────────────────────────
Expand Down Expand Up @@ -90,7 +90,7 @@ Still having issues?
📝 LICENSE
───────────────────────────────────────────────────────────

HeartMuLa Studio is open source (MIT License)
CTFN Studio is open source (MIT License)
Built on HeartLib: https://github.com/HeartMuLa/heartlib

═══════════════════════════════════════════════════════════
Expand Down
42 changes: 21 additions & 21 deletions .github/workflows/build-macos-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ jobs:

- name: Check build/macos assets (icon, codesign, DMG README)
run: |
if [ ! -f "build/macos/HeartMuLa.icns" ]; then
echo "::error::build/macos/HeartMuLa.icns not found after generation."
if [ ! -f "build/macos/CTFNStudio.icns" ]; then
echo "::error::build/macos/CTFNStudio.icns not found after generation."
exit 1
fi
if [ ! -f "build/macos/codesign.sh" ]; then
Expand All @@ -82,38 +82,38 @@ jobs:

- name: Clean previous PyInstaller outputs
run: |
rm -rf dist/HeartMuLa.app build/HeartMuLa
rm -rf dist/CTFNStudio.app build/CTFNStudio

- name: Build with PyInstaller
run: |
python -m PyInstaller HeartMuLa.spec --clean --noconfirm

- name: Set up app bundle executable
run: |
# CFBundleExecutable is "HeartMuLa"; PyInstaller produces HeartMuLa_bin
# CFBundleExecutable is "CTFNStudio"; PyInstaller produces CTFNStudio_bin
# Copy so the app runs the real binary (native, no terminal)
cp dist/HeartMuLa.app/Contents/MacOS/HeartMuLa_bin dist/HeartMuLa.app/Contents/MacOS/HeartMuLa
chmod +x dist/HeartMuLa.app/Contents/MacOS/HeartMuLa
cp dist/CTFNStudio.app/Contents/MacOS/CTFNStudio_bin dist/CTFNStudio.app/Contents/MacOS/CTFNStudio
chmod +x dist/CTFNStudio.app/Contents/MacOS/CTFNStudio

- name: Code sign the app bundle
run: |
# Run the code signing script with ad-hoc signing (no certificate required for dev builds)
# This prevents the "app is damaged" warning that requires sudo xattr -cr
# For production releases, set MACOS_SIGNING_IDENTITY secret to your Developer ID
chmod +x build/macos/codesign.sh
./build/macos/codesign.sh dist/HeartMuLa.app
./build/macos/codesign.sh dist/CTFNStudio.app
env:
MACOS_SIGNING_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY || '-' }}

- name: Create DMG (macOS disk image)
run: |
# Create a temporary directory for DMG contents
mkdir -p dmg_temp
cp -R dist/HeartMuLa.app dmg_temp/
cp -R dist/CTFNStudio.app dmg_temp/

# Copy the .command file for easy launching
cp HeartMuLa.command dmg_temp/
chmod +x dmg_temp/HeartMuLa.command
cp CTFNStudio.command dmg_temp/
chmod +x dmg_temp/CTFNStudio.command

# Create Applications symlink for easy drag-and-drop install
ln -s /Applications dmg_temp/Applications
Expand All @@ -122,40 +122,40 @@ jobs:
cp .github/DMG_README.txt dmg_temp/README.txt

# Create DMG
hdiutil create -volname "HeartMuLa Studio" \
hdiutil create -volname "CTFN Studio" \
-srcfolder dmg_temp \
-ov -format UDZO \
HeartMuLa-macOS.dmg
CTFNStudio-macOS.dmg

- name: Create ZIP archive (alternative distribution)
run: |
cd dist
zip -r ../HeartMuLa-macOS.zip HeartMuLa.app
zip -r ../CTFNStudio-macOS.zip CTFNStudio.app
cd ..

- name: Calculate checksums
run: |
shasum -a 256 HeartMuLa-macOS.dmg > checksums.txt
shasum -a 256 HeartMuLa-macOS.zip >> checksums.txt
shasum -a 256 CTFNStudio-macOS.dmg > checksums.txt
shasum -a 256 CTFNStudio-macOS.zip >> checksums.txt
cat checksums.txt

- name: Upload DMG artifact
uses: actions/upload-artifact@v4
with:
name: HeartMuLa-macOS-DMG
path: HeartMuLa-macOS.dmg
name: CTFNStudio-macOS-DMG
path: CTFNStudio-macOS.dmg

- name: Upload ZIP artifact
uses: actions/upload-artifact@v4
with:
name: HeartMuLa-macOS-ZIP
path: HeartMuLa-macOS.zip
name: CTFNStudio-macOS-ZIP
path: CTFNStudio-macOS.zip

- name: Upload to Release (if triggered by release)
if: github.event_name == 'release'
uses: softprops/action-gh-release@v1
with:
files: |
HeartMuLa-macOS.dmg
HeartMuLa-macOS.zip
CTFNStudio-macOS.dmg
CTFNStudio-macOS.zip
checksums.txt
14 changes: 14 additions & 0 deletions CTFNStudio.command
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
# CTFN Studio Launcher
# Double-click this file to launch CTFN Studio

# Get the directory where this script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

# Launch the app
echo "Starting CTFN Studio..."
open -a "CTFNStudio.app"

# Keep the terminal open briefly to show any errors
sleep 2
14 changes: 7 additions & 7 deletions HeartMuLa.spec
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# -*- mode: python ; coding: utf-8 -*-
# PyInstaller spec file for HeartMuLa Studio macOS App
# PyInstaller spec file for CTFN Studio macOS App

import os
import sys
from PyInstaller.utils.hooks import collect_data_files, collect_submodules

# Get the current directory
block_cipher = None
app_name = 'HeartMuLa'
app_name = 'CTFNStudio'

# Collect data files from various packages
datas = []
Expand Down Expand Up @@ -73,7 +73,7 @@ exe = EXE(
bootloader_ignore_signals=False,
strip=False,
upx=False, # Disabled for macOS - UPX can cause issues with code signing
console=False, # No console window for cleaner UI experience. Check ~/Library/Logs/HeartMuLa/ for logs
console=False, # No console window for cleaner UI experience. Check ~/Library/Logs/HeartMuLa/ for logs (data path unchanged for compatibility)
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
Expand All @@ -95,12 +95,12 @@ coll = COLLECT(
app = BUNDLE(
coll,
name=f'{app_name}.app',
icon='build/macos/HeartMuLa.icns',
icon='build/macos/CTFNStudio.icns',
bundle_identifier='com.audiohacking.heartmula',
version='0.1.0',
info_plist={
'CFBundleName': 'HeartMuLa Studio',
'CFBundleDisplayName': 'HeartMuLa Studio',
'CFBundleName': 'CTFN Studio',
'CFBundleDisplayName': 'CTFN Studio',
'CFBundleExecutable': app_name,
'CFBundleIdentifier': 'com.audiohacking.heartmula',
'CFBundleVersion': '0.1.0',
Expand All @@ -111,7 +111,7 @@ app = BUNDLE(
'NSAppTransportSecurity': {
'NSAllowsArbitraryLoads': True
},
'NSMicrophoneUsageDescription': 'HeartMuLa Studio needs access to the microphone for audio input.',
'NSMicrophoneUsageDescription': 'CTFN Studio needs access to the microphone for audio input.',
'LSApplicationCategoryType': 'public.app-category.music',
},
)
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<p align="center">
<img src="https://raw.githubusercontent.com/audiohacking/HeartMuLa-Studio/main/frontend/public/heartmula-icon.svg" alt="HeartMuLa Studio" width="120" height="120">
<img src="https://raw.githubusercontent.com/audiohacking/HeartMuLa-Studio/main/frontend/public/ctfn-icon.png" alt="CTFN Studio" width="120" height="120">
</p>

<h1 align="center">HeartMuLa Studio</h1>
<h1 align="center">CTFN Studio</h1>

<p align="center">
<strong>Apple Silicon / MPS fork — AI music generation studio for <a href="https://github.com/HeartMuLa/heartlib">HeartLib</a>, optimized for Apple Metal (M-Series &amp; Intel Macs)</strong>
Expand All @@ -29,7 +29,7 @@

## About this fork

This repository is a **fork of HeartMuLa Studio** focused on **Apple MPS (Metal Performance Shaders)**
This repository is a **fork of HeartMuLa Studio** (rebranded as **CTFN Studio**) focused on **Apple MPS (Metal Performance Shaders)**

- **Native macOS app** — Standalone `.app` with native window (pywebview/Cocoa)
- **MPS-accelerated inference** — HeartMuLa and HeartCodec run on Metal where supported
Expand All @@ -43,7 +43,7 @@ For CUDA, Linux, or Windows setups, see the upstream project.
## Demo

<p align="center">
<img src="preview.gif" alt="HeartMuLa Studio Preview" width="100%">
<img src="preview.gif" alt="CTFN Studio Preview" width="100%">
</p>

---
Expand Down Expand Up @@ -119,11 +119,11 @@ Models are **auto-downloaded** from Hugging Face on first run (~5GB): HeartMuLa,

### macOS App (recommended)

1. Download the latest **HeartMuLa-macOS.dmg** (or `.zip`) from [Releases](https://github.com/audiohacking/HeartMuLa-Studio/releases).
2. Open the DMG and drag **HeartMuLa.app** to Applications.
1. Download the latest **CTFNStudio-macOS.dmg** (or `.zip`) from [Releases](https://github.com/audiohacking/HeartMuLa-Studio/releases).
2. Open the DMG and drag **CTFN Studio.app** to Applications.
3. Double-click to launch. If macOS blocks it, use **Right-click → Open**, or run:
```bash
xattr -cr /Applications/HeartMuLa.app
xattr -cr /Applications/CTFNStudio.app
```

**Data is stored in your user Library**, not inside the app:
Expand Down Expand Up @@ -240,7 +240,7 @@ OLLAMA_HOST=http://localhost:11434 # Local LLM
| Frontend can’t connect | Ensure backend is running on port 8000 |
| LLM not working | Run Ollama locally or set OpenRouter API key in `backend/.env` |
| Slow or high memory | Try `HEARTMULA_4BIT=true` or `HEARTMULA_SEQUENTIAL_OFFLOAD=true` |
| macOS app won’t open | Use Right-click → Open, or `xattr -cr /Applications/HeartMuLa.app` |
| macOS app won’t open | Use Right-click → Open, or `xattr -cr /Applications/CTFNStudio.app` |

---

Expand All @@ -250,7 +250,7 @@ OLLAMA_HOST=http://localhost:11434 # Local LLM
./local_build.sh
```

This installs deps, builds the frontend, generates the icon, runs PyInstaller, and signs the bundle. Output: `dist/HeartMuLa.app`. See [build/macos/README.md](build/macos/README.md) and [.github/workflows/build-macos-release.yml](.github/workflows/build-macos-release.yml) for details.
This installs deps, builds the frontend, generates the icon, runs PyInstaller, and signs the bundle. Output: `dist/CTFNStudio.app`. See [build/macos/README.md](build/macos/README.md) and [.github/workflows/build-macos-release.yml](.github/workflows/build-macos-release.yml) for details.

---

Expand All @@ -259,7 +259,7 @@ This installs deps, builds the frontend, generates the icon, runs PyInstaller, a
- **[HeartMuLa/heartlib](https://github.com/HeartMuLa/heartlib)** — Open-source AI music generation engine used by this project.
- **WaveSurfer.js** — Audio waveform visualization.

This fork is maintained for Apple MPS / Metal and is not affiliated with the upstream HeartMuLa project beyond use of HeartLib.
CTFN Studio is maintained for Apple MPS / Metal. The underlying AI engine is [HeartMuLa/heartlib](https://github.com/HeartMuLa/heartlib); this project is not affiliated with the upstream HeartMuLa project beyond use of HeartLib.

---

Expand Down
2 changes: 1 addition & 1 deletion backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async def lifespan(app: FastAPI):
event_manager.shutdown()
music_service.shutdown_all()

app = FastAPI(lifespan=lifespan, title="HeartMuLa Music API")
app = FastAPI(lifespan=lifespan, title="CTFN Studio API")

# CORS
app.add_middleware(
Expand Down
7 changes: 4 additions & 3 deletions backend/app/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import datetime, timezone
from typing import Optional
from typing import Optional, Union
from uuid import UUID, uuid4
from sqlmodel import Field, SQLModel
from enum import Enum
Expand Down Expand Up @@ -111,13 +111,14 @@ class AddToPlaylistRequest(SQLModel):
class GPUInfo(SQLModel):
index: int
name: str
vram_gb: float
compute_capability: float
vram_gb: Union[float, str] # float for CUDA VRAM, "Unified Memory" for MPS
compute_capability: Union[float, str] # float for CUDA SM, "MPS" for Apple Metal
supports_flash_attention: bool


class GPUStatusResponse(SQLModel):
cuda_available: bool
mps_available: bool = False # Apple Metal (MPS)
num_gpus: int
gpus: list
total_vram_gb: float
Expand Down
24 changes: 12 additions & 12 deletions build/macos/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# HeartMuLa Studio - macOS Build
# CTFN Studio - macOS Build

This directory contains assets and scripts for building HeartMuLa Studio as a standalone macOS application using PyInstaller.
This directory contains assets and scripts for building CTFN Studio as a standalone macOS application using PyInstaller.

## Directory Structure

```
build/macos/
├── HeartMuLa.icns # App icon (generated from SVG)
├── CTFNStudio.icns # App icon (generated from frontend/public/ctfn-icon.png)
├── codesign.sh # Code signing script
├── generate_icon.sh # Script to generate .icns from SVG
├── generate_icon.sh # Script to generate .icns from PNG
└── hooks/
└── hook-heartlib.py # PyInstaller hook for heartlib
```
Expand Down Expand Up @@ -76,23 +76,23 @@ pyinstaller HeartMuLa.spec --clean --noconfirm

5. Set up executable:
```bash
cp dist/HeartMuLa.app/Contents/MacOS/HeartMuLa_bin dist/HeartMuLa.app/Contents/MacOS/HeartMuLa
chmod +x dist/HeartMuLa.app/Contents/MacOS/HeartMuLa
cp dist/CTFNStudio.app/Contents/MacOS/CTFNStudio_bin dist/CTFNStudio.app/Contents/MacOS/CTFNStudio
chmod +x dist/CTFNStudio.app/Contents/MacOS/CTFNStudio
```

6. Code sign:
```bash
./build/macos/codesign.sh dist/HeartMuLa.app
./build/macos/codesign.sh dist/CTFNStudio.app
```

7. Create DMG:
```bash
mkdir -p dmg_temp
cp -R dist/HeartMuLa.app dmg_temp/
cp HeartMuLa.command dmg_temp/
cp -R dist/CTFNStudio.app dmg_temp/
cp CTFNStudio.command dmg_temp/
ln -s /Applications dmg_temp/Applications
cp .github/DMG_README.txt dmg_temp/README.txt
hdiutil create -volname "HeartMuLa Studio" -srcfolder dmg_temp -ov -format UDZO HeartMuLa-macOS.dmg
hdiutil create -volname "CTFN Studio" -srcfolder dmg_temp -ov -format UDZO CTFNStudio-macOS.dmg
```

### GitHub Actions
Expand Down Expand Up @@ -156,9 +156,9 @@ For production releases, set the `MACOS_SIGNING_IDENTITY` secret in GitHub to yo

### Icon not generating

Install the required tools:
Ensure `frontend/public/ctfn-icon.png` exists. Install ImageMagick or use sips:
```bash
brew install librsvg imagemagick
brew install imagemagick
```

### PyInstaller errors
Expand Down
2 changes: 1 addition & 1 deletion build/macos/codesign.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
# Code signing script for HeartMuLa Studio macOS app
# Code signing script for CTFN Studio macOS app
# This script signs the app bundle to prevent "app is damaged" warnings

set -e
Expand Down
Loading