Rename application identifier to space.rcmd.android.sizzle

Global rename of the app/package identifier from
com.reactorcoremeltdown.sizzletracker to space.rcmd.android.sizzle:

- build.gradle.kts: applicationId + namespace.
- Move the Kotlin source tree (main + test) and rewrite every package/import.
- native_audio.cpp: JNI symbol names (Java_space_rcmd_android_sizzle_...) so the
  Oboe callback still links against the relocated NativeAudioBridge.
- docs: package/file-map header.

The desktop-project GitHub URLs (github.com/reactorcoremeltdown/sizzletracker)
and the Reactorcoremeltdown copyright/SPDX author identity are intentionally left
unchanged. Note: the new applicationId installs as a separate package (existing
installs won't upgrade in place).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Reactorcoremeltdown
2026-07-17 18:59:51 +02:00
parent a5fdc7b6c4
commit 4bd8aac4d5
61 changed files with 289 additions and 289 deletions

View File

@@ -8,7 +8,7 @@ plugins {
}
android {
namespace = "com.reactorcoremeltdown.sizzletracker"
namespace = "space.rcmd.android.sizzle"
compileSdk = 34
// Native (Oboe) low-latency output backend; see src/main/cpp.
@@ -17,7 +17,7 @@ android {
ndkVersion = "27.2.12479018"
defaultConfig {
applicationId = "com.reactorcoremeltdown.sizzletracker"
applicationId = "space.rcmd.android.sizzle"
// minSdk 26 (Android 8.0) is the floor for the native MIDI API
// (android.media.midi) and AAudio low-latency audio we rely on.
minSdk = 26

View File

@@ -214,7 +214,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void * /*reserved*/) {
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_reactorcoremeltdown_sizzletracker_audio_NativeAudioBridge_nativeStart(
Java_space_rcmd_android_sizzle_audio_NativeAudioBridge_nativeStart(
JNIEnv *env, jobject /*thiz*/, jobject callback, jint sampleRate, jint framesPerCallback) {
g_callback = env->NewGlobalRef(callback);
jclass cls = env->GetObjectClass(callback);
@@ -241,7 +241,7 @@ Java_com_reactorcoremeltdown_sizzletracker_audio_NativeAudioBridge_nativeStart(
}
extern "C" JNIEXPORT void JNICALL
Java_com_reactorcoremeltdown_sizzletracker_audio_NativeAudioBridge_nativeStop(
Java_space_rcmd_android_sizzle_audio_NativeAudioBridge_nativeStop(
JNIEnv *env, jobject /*thiz*/) {
g_wantRunning = false; // stop the disconnect-recovery from reopening
if (g_stream) {

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker
package space.rcmd.android.sizzle
import android.Manifest
import android.content.pm.PackageManager
@@ -16,13 +16,13 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.reactorcoremeltdown.sizzletracker.input.GamepadInput
import com.reactorcoremeltdown.sizzletracker.input.KeyboardInput
import com.reactorcoremeltdown.sizzletracker.input.MidiInput
import com.reactorcoremeltdown.sizzletracker.playback.PlaybackService
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.SizzleApp as SizzleAppUi
import com.reactorcoremeltdown.sizzletracker.ui.theme.SizzleTheme
import space.rcmd.android.sizzle.input.GamepadInput
import space.rcmd.android.sizzle.input.KeyboardInput
import space.rcmd.android.sizzle.input.MidiInput
import space.rcmd.android.sizzle.playback.PlaybackService
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.SizzleApp as SizzleAppUi
import space.rcmd.android.sizzle.ui.theme.SizzleTheme
/**
* The single Activity. Its jobs are narrow and clear:

View File

@@ -1,21 +1,21 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker
package space.rcmd.android.sizzle
import android.app.Application
import com.reactorcoremeltdown.sizzletracker.audio.AudioEngine
import com.reactorcoremeltdown.sizzletracker.input.BindingStore
import com.reactorcoremeltdown.sizzletracker.input.GamepadInput
import com.reactorcoremeltdown.sizzletracker.input.InputRouter
import com.reactorcoremeltdown.sizzletracker.input.KeyboardInput
import com.reactorcoremeltdown.sizzletracker.input.MidiInput
import com.reactorcoremeltdown.sizzletracker.io.PresetLibrary
import com.reactorcoremeltdown.sizzletracker.io.ProjectStore
import com.reactorcoremeltdown.sizzletracker.io.SettingsStore
import com.reactorcoremeltdown.sizzletracker.io.SongLibrary
import com.reactorcoremeltdown.sizzletracker.io.ThemeLibrary
import com.reactorcoremeltdown.sizzletracker.model.Project
import space.rcmd.android.sizzle.audio.AudioEngine
import space.rcmd.android.sizzle.input.BindingStore
import space.rcmd.android.sizzle.input.GamepadInput
import space.rcmd.android.sizzle.input.InputRouter
import space.rcmd.android.sizzle.input.KeyboardInput
import space.rcmd.android.sizzle.input.MidiInput
import space.rcmd.android.sizzle.io.PresetLibrary
import space.rcmd.android.sizzle.io.ProjectStore
import space.rcmd.android.sizzle.io.SettingsStore
import space.rcmd.android.sizzle.io.SongLibrary
import space.rcmd.android.sizzle.io.ThemeLibrary
import space.rcmd.android.sizzle.model.Project
import java.io.File
import kotlinx.coroutines.runBlocking

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
import com.reactorcoremeltdown.sizzletracker.model.AmbiencePresets
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import space.rcmd.android.sizzle.model.AmbiencePresets
import space.rcmd.android.sizzle.model.ToolboxSlot
import kotlin.math.abs
import kotlin.math.exp
import kotlin.math.floor

View File

@@ -1,18 +1,18 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
import android.media.AudioAttributes
import android.media.AudioFormat
import android.media.AudioTrack
import com.reactorcoremeltdown.sizzletracker.model.Arrangement
import com.reactorcoremeltdown.sizzletracker.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Project
import com.reactorcoremeltdown.sizzletracker.model.SamplerPads
import com.reactorcoremeltdown.sizzletracker.model.TimeDivision
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType
import space.rcmd.android.sizzle.model.Arrangement
import space.rcmd.android.sizzle.model.Pattern
import space.rcmd.android.sizzle.model.Project
import space.rcmd.android.sizzle.model.SamplerPads
import space.rcmd.android.sizzle.model.TimeDivision
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.model.ToolboxType
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlin.concurrent.thread
@@ -682,7 +682,7 @@ class AudioEngine(
* its own MIDI effects (Transposer shifts pitch; an Arpeggiator captures the
* note and hands retriggering to [advanceArps]).
*/
private fun triggerCell(proj: Project, lane: Int, cell: com.reactorcoremeltdown.sizzletracker.model.Cell) {
private fun triggerCell(proj: Project, lane: Int, cell: space.rcmd.android.sizzle.model.Cell) {
for (bus in 0 until Pattern.TRACK_COUNT) {
if (proj.mixer.channels[bus].midiChannel != cell.channel) continue
val arp = arps[lane * Pattern.TRACK_COUNT + bus]

View File

@@ -1,11 +1,11 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
import com.reactorcoremeltdown.sizzletracker.model.DelayDivisions
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType
import space.rcmd.android.sizzle.model.DelayDivisions
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.model.ToolboxType
import kotlin.math.PI
import kotlin.math.abs
import kotlin.math.cos

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
import java.io.File
import java.io.RandomAccessFile

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
/**
* Bridges the native Oboe (AAudio) output backend to the Kotlin [AudioEngine].

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
import android.annotation.SuppressLint
import android.media.AudioFormat

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
import java.nio.ByteBuffer
import java.nio.ByteOrder

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
import kotlin.math.exp

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
import java.nio.ByteBuffer
import java.nio.ByteOrder

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
/**
* One playing note (a "voice"). This is a deliberately simple NES/Famicom-style

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio
package space.rcmd.android.sizzle.audio
/**
* A small, immutable snapshot of "where playback is" that the audio thread

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input
package space.rcmd.android.sizzle.input
import android.content.Context
import androidx.datastore.core.DataStore

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input
package space.rcmd.android.sizzle.input
import android.view.InputDevice
import android.view.KeyEvent

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input
package space.rcmd.android.sizzle.input
/**
* The heart of the "four equal input methods" requirement. Touch, physical

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input
package space.rcmd.android.sizzle.input
/**
* The single source of truth mapping a stable action-id string to the neutral

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input
package space.rcmd.android.sizzle.input
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input
package space.rcmd.android.sizzle.input
import android.view.KeyEvent
import com.reactorcoremeltdown.sizzletracker.model.Pitch
import space.rcmd.android.sizzle.model.Pitch
/**
* Translates physical (USB / Bluetooth) keyboard events into [InputAction]s.

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input
package space.rcmd.android.sizzle.input
import android.content.Context
import android.media.midi.MidiDeviceInfo

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.model.ToolboxType
/**
* Reads and writes a single instrument/effect preset as plain, human-readable

View File

@@ -1,14 +1,14 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.audio.SampleStore
import com.reactorcoremeltdown.sizzletracker.model.AmbiencePresets
import com.reactorcoremeltdown.sizzletracker.model.Project
import com.reactorcoremeltdown.sizzletracker.model.SamplerPads
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType
import space.rcmd.android.sizzle.audio.SampleStore
import space.rcmd.android.sizzle.model.AmbiencePresets
import space.rcmd.android.sizzle.model.Project
import space.rcmd.android.sizzle.model.SamplerPads
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.model.ToolboxType
import java.io.File
import java.io.InputStream
import java.util.zip.ZipEntry

View File

@@ -1,15 +1,15 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.Cell
import com.reactorcoremeltdown.sizzletracker.model.Mixer
import com.reactorcoremeltdown.sizzletracker.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Project
import com.reactorcoremeltdown.sizzletracker.model.Scale
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType
import space.rcmd.android.sizzle.model.Cell
import space.rcmd.android.sizzle.model.Mixer
import space.rcmd.android.sizzle.model.Pattern
import space.rcmd.android.sizzle.model.Project
import space.rcmd.android.sizzle.model.Scale
import space.rcmd.android.sizzle.model.TimeSignature
import space.rcmd.android.sizzle.model.ToolboxType
/**
* Saves and loads a whole [Project] to/from the `.sng` text format.
@@ -87,7 +87,7 @@ object ProjectIo {
// Reset everything to a clean slate first.
project.patterns.clear()
for (lane in project.arrangement.slots.indices)
project.arrangement.slots[lane].fill(com.reactorcoremeltdown.sizzletracker.model.Arrangement.EMPTY)
project.arrangement.slots[lane].fill(space.rcmd.android.sizzle.model.Arrangement.EMPTY)
project.arrangement.laneMuted.fill(false)
project.toolbox.forEach { it.clearSlot() }
project.mixer.channels.forEach { ch ->
@@ -119,7 +119,7 @@ object ProjectIo {
// are restored from the explicit lane,beat,pid lines regardless).
project.arrangement.lengthBars =
attrs["bars"]?.toIntOrNull()
?: com.reactorcoremeltdown.sizzletracker.model.Arrangement.MAX_BARS
?: space.rcmd.android.sizzle.model.Arrangement.MAX_BARS
project.arrangement.loopEnabled = attrs["loop"] == "1"
attrs["mutes"]?.let { m ->
val lanes = project.arrangement.laneMuted
@@ -142,7 +142,7 @@ object ProjectIo {
}
// Guarantee one block per lane (lane i is tied to block i), padding any
// that the file did not define so the arrangement/editor always resolve.
for (id in 0 until com.reactorcoremeltdown.sizzletracker.model.Arrangement.LANE_COUNT) {
for (id in 0 until space.rcmd.android.sizzle.model.Arrangement.LANE_COUNT) {
if (project.patterns.none { it.id == id }) project.patterns.add(Pattern(id, name = "BLK${id + 1}"))
}
project.patterns.sortBy { it.id }
@@ -193,7 +193,7 @@ object ProjectIo {
p.arrangement.set(lane, beat, pid)
}
private fun applyRegion(region: com.reactorcoremeltdown.sizzletracker.model.LoopRegion, a: Map<String, String>) {
private fun applyRegion(region: space.rcmd.android.sizzle.model.LoopRegion, a: Map<String, String>) {
region.enabled = a["en"] == "1"
region.start = a["s"]?.toIntOrNull() ?: 0
region.end = a["e"]?.toIntOrNull() ?: 0

View File

@@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.Project
import space.rcmd.android.sizzle.model.Project
import java.io.File
/**

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import android.content.Context
import androidx.datastore.core.DataStore
@@ -32,7 +32,7 @@ data class AppSettings(
* Persists app-level UI/audio settings (the colour theme and the low-latency
* engine toggle). Song/mixer/toolbox parameters live in the project and are
* handled by [ProjectStore]; input bindings by
* [com.reactorcoremeltdown.sizzletracker.input.BindingStore].
* [space.rcmd.android.sizzle.input.BindingStore].
*
* Audio output/input *device* selection is intentionally not persisted: Android
* device ids are session-scoped and don't identify the same hardware next launch.

View File

@@ -1,14 +1,14 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.Arrangement
import com.reactorcoremeltdown.sizzletracker.model.Cell
import com.reactorcoremeltdown.sizzletracker.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.Project
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature
import space.rcmd.android.sizzle.model.Arrangement
import space.rcmd.android.sizzle.model.Cell
import space.rcmd.android.sizzle.model.Pattern
import space.rcmd.android.sizzle.model.Pitch
import space.rcmd.android.sizzle.model.Project
import space.rcmd.android.sizzle.model.TimeSignature
/**
* Reads and writes the reference desktop **sizzletracker `.sng`** format

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import java.io.File

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import androidx.compose.ui.graphics.Color
import com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette
import space.rcmd.android.sizzle.ui.theme.RetroPalette
/**
* Reads and writes a colour [RetroPalette] as plain, human-editable text the same

View File

@@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette
import space.rcmd.android.sizzle.ui.theme.RetroPalette
import java.io.File
/**

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model
package space.rcmd.android.sizzle.model
/**
* Factory data for the [ToolboxType.AMBIENCE] reverb, ported from OTODESK's

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model
package space.rcmd.android.sizzle.model
/**
* The lower-half piano-roll arrangement. It has [LANE_COUNT] lanes stacked

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model
package space.rcmd.android.sizzle.model
/**
* The mixer has exactly [CHANNEL_COUNT] channels, one per tracker track. Each

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model
package space.rcmd.android.sizzle.model
/**
* Musical primitives shared across the whole app: pitches, scales and time

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model
package space.rcmd.android.sizzle.model
/**
* One cell in the tracker grid: a single note event on a single line of a single

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model
package space.rcmd.android.sizzle.model
/**
* The whole song in memory. This single object is what gets saved to / loaded
@@ -9,7 +9,7 @@ package com.reactorcoremeltdown.sizzletracker.model
* Keeping one root object makes serialization and undo/redo straightforward.
*
* Persistence is done by our own text serializer (see
* [com.reactorcoremeltdown.sizzletracker.io.ProjectIo]), not kotlinx, so the
* [space.rcmd.android.sizzle.io.ProjectIo]), not kotlinx, so the
* model classes carry no serialization annotations.
*/
class Project {

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model
package space.rcmd.android.sizzle.model
/**
* The third tab is a toolbox of 16 slots. Every slot can hold one instrument OR
@@ -273,7 +273,7 @@ enum class TimeDivision(val label: String, val beatFraction: Double) {
* sample file path live in the same map under keys the engine knows about
* (e.g. "samplePath", "target").
*
* (Serialized via [com.reactorcoremeltdown.sizzletracker.io.PresetIo], not
* (Serialized via [space.rcmd.android.sizzle.io.PresetIo], not
* kotlinx, so no @Serializable annotation is needed here.)
*/
class ToolboxSlot(

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.playback
package space.rcmd.android.sizzle.playback
import android.os.Looper
import androidx.media3.common.MediaItem
@@ -11,7 +11,7 @@ import androidx.media3.common.SimpleBasePlayer
import androidx.media3.common.util.UnstableApi
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import com.reactorcoremeltdown.sizzletracker.audio.AudioEngine
import space.rcmd.android.sizzle.audio.AudioEngine
/**
* Adapts our custom [AudioEngine] to the media3 [Player] interface via

View File

@@ -1,14 +1,14 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.playback
package space.rcmd.android.sizzle.playback
import android.content.Context
import android.content.Intent
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import com.reactorcoremeltdown.sizzletracker.SizzleApp
import space.rcmd.android.sizzle.SizzleApp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui
package space.rcmd.android.sizzle.ui
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
@@ -29,11 +29,11 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import com.reactorcoremeltdown.sizzletracker.ui.mixer.MixerScreen
import com.reactorcoremeltdown.sizzletracker.ui.settings.SettingsScreen
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import com.reactorcoremeltdown.sizzletracker.ui.toolbox.ToolboxScreen
import com.reactorcoremeltdown.sizzletracker.ui.tracker.TrackerScreen
import space.rcmd.android.sizzle.ui.mixer.MixerScreen
import space.rcmd.android.sizzle.ui.settings.SettingsScreen
import space.rcmd.android.sizzle.ui.theme.LocalRetro
import space.rcmd.android.sizzle.ui.toolbox.ToolboxScreen
import space.rcmd.android.sizzle.ui.tracker.TrackerScreen
/**
* The top-level layout: the active tab's screen fills the space above a standard

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui
package space.rcmd.android.sizzle.ui
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
@@ -10,15 +10,15 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.reactorcoremeltdown.sizzletracker.audio.AudioEngine
import com.reactorcoremeltdown.sizzletracker.input.InputAction
import com.reactorcoremeltdown.sizzletracker.input.InputRouter
import com.reactorcoremeltdown.sizzletracker.model.Cell
import com.reactorcoremeltdown.sizzletracker.model.CellColumn
import com.reactorcoremeltdown.sizzletracker.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.Project
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature
import space.rcmd.android.sizzle.audio.AudioEngine
import space.rcmd.android.sizzle.input.InputAction
import space.rcmd.android.sizzle.input.InputRouter
import space.rcmd.android.sizzle.model.Cell
import space.rcmd.android.sizzle.model.CellColumn
import space.rcmd.android.sizzle.model.Pattern
import space.rcmd.android.sizzle.model.Pitch
import space.rcmd.android.sizzle.model.Project
import space.rcmd.android.sizzle.model.TimeSignature
import kotlinx.coroutines.launch
/**
@@ -36,14 +36,14 @@ class AppViewModel(
val project: Project,
private val engine: AudioEngine,
private val router: InputRouter,
private val gamepadInput: com.reactorcoremeltdown.sizzletracker.input.GamepadInput,
private val midiInput: com.reactorcoremeltdown.sizzletracker.input.MidiInput,
private val keyboardInput: com.reactorcoremeltdown.sizzletracker.input.KeyboardInput,
private val bindingStore: com.reactorcoremeltdown.sizzletracker.input.BindingStore,
private val presetLibrary: com.reactorcoremeltdown.sizzletracker.io.PresetLibrary,
private val songLibrary: com.reactorcoremeltdown.sizzletracker.io.SongLibrary,
private val settingsStore: com.reactorcoremeltdown.sizzletracker.io.SettingsStore,
private val themeLibrary: com.reactorcoremeltdown.sizzletracker.io.ThemeLibrary,
private val gamepadInput: space.rcmd.android.sizzle.input.GamepadInput,
private val midiInput: space.rcmd.android.sizzle.input.MidiInput,
private val keyboardInput: space.rcmd.android.sizzle.input.KeyboardInput,
private val bindingStore: space.rcmd.android.sizzle.input.BindingStore,
private val presetLibrary: space.rcmd.android.sizzle.io.PresetLibrary,
private val songLibrary: space.rcmd.android.sizzle.io.SongLibrary,
private val settingsStore: space.rcmd.android.sizzle.io.SettingsStore,
private val themeLibrary: space.rcmd.android.sizzle.io.ThemeLibrary,
private val appContext: android.content.Context,
) : ViewModel() {
@@ -52,7 +52,7 @@ class AppViewModel(
var revision by mutableIntStateOf(0); private set // bump to force grid redraw
/** Active colour theme; read by [MainActivity] to drive SizzleTheme. Set via
* [selectPalette] so the choice is persisted. */
var palette by mutableStateOf(com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette.AMBER)
var palette by mutableStateOf(space.rcmd.android.sizzle.ui.theme.RetroPalette.AMBER)
private set
// Tracker cursor position.
@@ -110,7 +110,7 @@ class AppViewModel(
// ----- Binding-learn state (Settings tab) -----
/** The action id currently waiting to be bound, or null. */
var learnTarget by mutableStateOf<String?>(null); private set
private var learnSource: com.reactorcoremeltdown.sizzletracker.input.InputSource? = null
private var learnSource: space.rcmd.android.sizzle.input.InputSource? = null
init {
// Collect neutral input actions from every non-touch device.
@@ -444,7 +444,7 @@ class AppViewModel(
// ------------------------------------------------------- binding learn
/** Arm MIDI-learn / gamepad-rebind: the next matching control is bound to
* [actionId]. [source] restricts which device kind will be captured. */
fun beginLearn(actionId: String, source: com.reactorcoremeltdown.sizzletracker.input.InputSource) {
fun beginLearn(actionId: String, source: space.rcmd.android.sizzle.input.InputSource) {
learnTarget = actionId
learnSource = source
router.learnSource = source
@@ -465,15 +465,15 @@ class AppViewModel(
val target = learnTarget ?: return
if (action.source != learnSource) return
when (action.source) {
com.reactorcoremeltdown.sizzletracker.input.InputSource.MIDI ->
space.rcmd.android.sizzle.input.InputSource.MIDI ->
midiInput.ccBindings[action.code] = target
com.reactorcoremeltdown.sizzletracker.input.InputSource.GAMEPAD -> {
space.rcmd.android.sizzle.input.InputSource.GAMEPAD -> {
gamepadInput.bindings.entries.removeAll { it.value == target }
gamepadInput.bindings[
com.reactorcoremeltdown.sizzletracker.input.GamepadChord(action.modifier, action.code),
space.rcmd.android.sizzle.input.GamepadChord(action.modifier, action.code),
] = target
}
com.reactorcoremeltdown.sizzletracker.input.InputSource.KEYBOARD -> {
space.rcmd.android.sizzle.input.InputSource.KEYBOARD -> {
keyboardInput.bindings.entries.removeAll { it.value == target }
keyboardInput.bindings[action.code] = target
}
@@ -490,20 +490,20 @@ class AppViewModel(
/** Current gamepad chord (modifier + button, or plain button) bound to
* [actionId], or null. */
fun gamepadBindingFor(actionId: String): com.reactorcoremeltdown.sizzletracker.input.GamepadChord? =
fun gamepadBindingFor(actionId: String): space.rcmd.android.sizzle.input.GamepadChord? =
gamepadInput.bindings.entries.firstOrNull { it.value == actionId }?.key
/** Current keyboard key code bound to [actionId], or null. */
fun keyboardBindingFor(actionId: String): Int? =
keyboardInput.bindings.entries.firstOrNull { it.value == actionId }?.key
fun clearBinding(actionId: String, source: com.reactorcoremeltdown.sizzletracker.input.InputSource) {
fun clearBinding(actionId: String, source: space.rcmd.android.sizzle.input.InputSource) {
when (source) {
com.reactorcoremeltdown.sizzletracker.input.InputSource.MIDI ->
space.rcmd.android.sizzle.input.InputSource.MIDI ->
midiInput.ccBindings.entries.removeAll { it.value == actionId }
com.reactorcoremeltdown.sizzletracker.input.InputSource.GAMEPAD ->
space.rcmd.android.sizzle.input.InputSource.GAMEPAD ->
gamepadInput.bindings.entries.removeAll { it.value == actionId }
com.reactorcoremeltdown.sizzletracker.input.InputSource.KEYBOARD ->
space.rcmd.android.sizzle.input.InputSource.KEYBOARD ->
keyboardInput.bindings.entries.removeAll { it.value == actionId }
else -> {}
}
@@ -538,26 +538,26 @@ class AppViewModel(
/** Nudge an A/B loop region's repeat count and apply it to live playback
* immediately (without restarting the transport). */
fun changeRegionRepeats(region: com.reactorcoremeltdown.sizzletracker.model.LoopRegion, delta: Int) {
fun changeRegionRepeats(region: space.rcmd.android.sizzle.model.LoopRegion, delta: Int) {
region.repeats = (region.repeats + delta).coerceAtLeast(1)
engine.refreshLoopPlaylist()
touched()
}
// -------------------------------------------------------------- sampler
private val recorder = com.reactorcoremeltdown.sizzletracker.audio.SampleRecorder()
private val recorder = space.rcmd.android.sizzle.audio.SampleRecorder()
var isRecording by mutableStateOf(false); private set
/** Decode a WAV and assign it to Sampler [slot]'s [pad] (from a file import). */
fun loadSampleInto(
slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot,
slot: space.rcmd.android.sizzle.model.ToolboxSlot,
pad: Int,
id: String,
bytes: ByteArray,
): Boolean {
val sample = com.reactorcoremeltdown.sizzletracker.audio.SampleStore.decodeWav(bytes) ?: return false
com.reactorcoremeltdown.sizzletracker.audio.SampleStore.put(id, sample)
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads
val sample = space.rcmd.android.sizzle.audio.SampleStore.decodeWav(bytes) ?: return false
space.rcmd.android.sizzle.audio.SampleStore.put(id, sample)
val pads = space.rcmd.android.sizzle.model.SamplerPads
slot.set(pads.key(pad), id)
slot.set(pads.sliceStartKey(pad), 0f); slot.set(pads.sliceEndKey(pad), 1f)
touched()
@@ -567,12 +567,12 @@ class AppViewModel(
/** Load an SF2 / XI (or WAV) file into a SoundFont [slot]: parse it, cache the
* extracted sample, and store its id + root note on the slot. */
fun loadSoundFont(
slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot,
slot: space.rcmd.android.sizzle.model.ToolboxSlot,
id: String,
bytes: ByteArray,
): Boolean {
val loaded = com.reactorcoremeltdown.sizzletracker.audio.SoundFontLoader.load(bytes) ?: return false
com.reactorcoremeltdown.sizzletracker.audio.SampleStore.put(id, loaded.sample)
val loaded = space.rcmd.android.sizzle.audio.SoundFontLoader.load(bytes) ?: return false
space.rcmd.android.sizzle.audio.SampleStore.put(id, loaded.sample)
slot.set("sfSample", id)
slot.set("sfRoot", loaded.rootNote.toFloat())
touched()
@@ -585,9 +585,9 @@ class AppViewModel(
* and the markers reset to the full (new) sample. There is no undo re-import
* or re-record to start over. Returns false if there's nothing to trim.
*/
fun trimSamplerPad(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, pad: Int): Boolean {
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads
val store = com.reactorcoremeltdown.sizzletracker.audio.SampleStore
fun trimSamplerPad(slot: space.rcmd.android.sizzle.model.ToolboxSlot, pad: Int): Boolean {
val pads = space.rcmd.android.sizzle.model.SamplerPads
val store = space.rcmd.android.sizzle.audio.SampleStore
val sample = store.get(slot.string(pads.key(pad))) ?: return false
val len = sample.data.size
if (len <= 1) return false
@@ -598,7 +598,7 @@ class AppViewModel(
if (start == 0 && end == len) return false // slice already spans the whole sample
// A fresh id so other pads sharing the original sample are left untouched.
val id = "trim:" + System.nanoTime()
store.put(id, com.reactorcoremeltdown.sizzletracker.audio.SampleStore.Sample(
store.put(id, space.rcmd.android.sizzle.audio.SampleStore.Sample(
sample.data.copyOfRange(start, end), sample.sampleRate))
slot.set(pads.key(pad), id)
slot.set(pads.sliceStartKey(pad), 0f)
@@ -613,9 +613,9 @@ class AppViewModel(
* the same). No undo. Returns false if the pad is empty, silent, or already
* normalized.
*/
fun normalizeSamplerPad(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, pad: Int): Boolean {
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads
val store = com.reactorcoremeltdown.sizzletracker.audio.SampleStore
fun normalizeSamplerPad(slot: space.rcmd.android.sizzle.model.ToolboxSlot, pad: Int): Boolean {
val pads = space.rcmd.android.sizzle.model.SamplerPads
val store = space.rcmd.android.sizzle.audio.SampleStore
val sample = store.get(slot.string(pads.key(pad))) ?: return false
val data = sample.data
if (data.isEmpty()) return false
@@ -626,15 +626,15 @@ class AppViewModel(
if (gain in 0.999f..1.001f) return false // already at full scale
val out = FloatArray(data.size) { (data[it] * gain).coerceIn(-1f, 1f) }
val id = "norm:" + System.nanoTime() // fresh id so shared samples are untouched
store.put(id, com.reactorcoremeltdown.sizzletracker.audio.SampleStore.Sample(out, sample.sampleRate))
store.put(id, space.rcmd.android.sizzle.audio.SampleStore.Sample(out, sample.sampleRate))
slot.set(pads.key(pad), id)
touched()
return true
}
/** Clear the sample assigned to a Sampler [slot]'s [pad]. */
fun clearSamplerPad(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, pad: Int) {
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads
fun clearSamplerPad(slot: space.rcmd.android.sizzle.model.ToolboxSlot, pad: Int) {
val pads = space.rcmd.android.sizzle.model.SamplerPads
slot.values.remove(pads.key(pad))
slot.values.remove(pads.sliceStartKey(pad))
slot.values.remove(pads.sliceEndKey(pad))
@@ -664,19 +664,19 @@ class AppViewModel(
fun dismissNativeAudioError() { nativeAudioError = null }
/** Choose the colour theme and persist the choice. */
fun selectPalette(p: com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette) {
fun selectPalette(p: space.rcmd.android.sizzle.ui.theme.RetroPalette) {
palette = p
persistSettings()
}
// ------------------------------------------------------------ colour themes
private val stockThemes get() = com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette.ALL
private val stockThemes get() = space.rcmd.android.sizzle.ui.theme.RetroPalette.ALL
/** The two built-in themes are read-only and can never be deleted. */
fun isStockTheme(name: String): Boolean = stockThemes.any { it.name == name }
/** Every selectable theme: the two stock themes followed by user themes. */
fun allThemes(): List<com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette> =
fun allThemes(): List<space.rcmd.android.sizzle.ui.theme.RetroPalette> =
stockThemes + themeLibrary.loadAll()
/** All theme names for the selector dropdown (stock first, then user). */
@@ -705,7 +705,7 @@ class AppViewModel(
if (isStockTheme(name)) return false
val ok = themeLibrary.delete(name)
if (ok) {
if (palette.name == name) selectPalette(com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette.AMBER)
if (palette.name == name) selectPalette(space.rcmd.android.sizzle.ui.theme.RetroPalette.AMBER)
touched()
}
return ok
@@ -759,13 +759,13 @@ class AppViewModel(
}
/** Stop recording and assign the captured audio to Sampler [slot]'s [pad]. */
fun stopRecordingInto(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, pad: Int) {
fun stopRecordingInto(slot: space.rcmd.android.sizzle.model.ToolboxSlot, pad: Int) {
val sample = recorder.stop()
isRecording = false
if (sample != null) {
val id = "rec-" + System.currentTimeMillis()
com.reactorcoremeltdown.sizzletracker.audio.SampleStore.put(id, sample)
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads
space.rcmd.android.sizzle.audio.SampleStore.put(id, sample)
val pads = space.rcmd.android.sizzle.model.SamplerPads
slot.set(pads.key(pad), id)
slot.set(pads.sliceStartKey(pad), 0f); slot.set(pads.sliceEndKey(pad), 1f)
touched()
@@ -775,7 +775,7 @@ class AppViewModel(
/** Point an LFO slot at another device's parameter, capturing that param's
* current value as the modulation centre. Pass targetSlotIndex < 0 to clear. */
fun setLfoTarget(
lfoSlot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot,
lfoSlot: space.rcmd.android.sizzle.model.ToolboxSlot,
targetSlotIndex: Int,
key: String,
) {
@@ -791,7 +791,7 @@ class AppViewModel(
}
/** Preview a note of the Sampler slot's loaded sample (one-shot, editor use). */
fun auditionSample(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, midi: Int) {
fun auditionSample(slot: space.rcmd.android.sizzle.model.ToolboxSlot, midi: Int) {
engine.auditionSlotOn(slot.index, midi)
}
@@ -803,18 +803,18 @@ class AppViewModel(
// ------------------------------------------------------------ project I/O
/** Serialize the current song to `.sng` text. */
fun saveProjectText(): String =
com.reactorcoremeltdown.sizzletracker.io.ProjectIo.save(project)
space.rcmd.android.sizzle.io.ProjectIo.save(project)
/** Replace the current song's contents from our full internal text (in place). */
fun loadProjectText(text: String) {
com.reactorcoremeltdown.sizzletracker.io.ProjectIo.loadInto(project, text)
space.rcmd.android.sizzle.io.ProjectIo.loadInto(project, text)
cursorLine = 0; cursorTrack = 0
touched()
}
/** Export to the reference desktop sizzletracker `.sng` format (musical data). */
fun exportSng(): String =
com.reactorcoremeltdown.sizzletracker.io.SngFormat.export(project)
space.rcmd.android.sizzle.io.SngFormat.export(project)
/** Import a reference `.sng` file (in place). Returns false if the text doesn't
* look like a `.sng` (so the caller can surface a popup) rather than silently
@@ -823,7 +823,7 @@ class AppViewModel(
val looksLikeSng = Regex("(?m)^\\s*(version|bpm|sig|block)\\b").containsMatchIn(text)
if (!looksLikeSng) return false
runCatching {
com.reactorcoremeltdown.sizzletracker.io.SngFormat.importInto(project, text)
space.rcmd.android.sizzle.io.SngFormat.importInto(project, text)
}.getOrElse { return false }
cursorLine = 0; cursorTrack = 0
touched()
@@ -854,7 +854,7 @@ class AppViewModel(
*/
fun newProject() {
engine.stop()
loadProjectText(com.reactorcoremeltdown.sizzletracker.io.ProjectIo.save(Project()))
loadProjectText(space.rcmd.android.sizzle.io.ProjectIo.save(Project()))
project.name = "untitled"
engine.rebuildFxChains() // all FX routing was cleared
}
@@ -882,11 +882,11 @@ class AppViewModel(
// ------------------------------------------------------ instrument/effect presets
/** Preset names available for a device type (for the editor's browser dropdown). */
fun presetNames(type: com.reactorcoremeltdown.sizzletracker.model.ToolboxType): List<String> =
fun presetNames(type: space.rcmd.android.sizzle.model.ToolboxType): List<String> =
presetLibrary.list(type)
/** Save [slot] as a named preset in the library. Returns the preset file. */
fun savePreset(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, name: String): java.io.File {
fun savePreset(slot: space.rcmd.android.sizzle.model.ToolboxSlot, name: String): java.io.File {
val file = presetLibrary.save(slot, name)
touched()
return file
@@ -894,7 +894,7 @@ class AppViewModel(
/** Load a named preset for [slot]'s current type into it. The slot is renamed to
* the preset so the toolbox tile and mixer inserts read as the loaded sound. */
fun loadPreset(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, name: String): Boolean {
fun loadPreset(slot: space.rcmd.android.sizzle.model.ToolboxSlot, name: String): Boolean {
val type = slot.type ?: return false
val ok = presetLibrary.load(slot, type, name)
if (ok) { slot.name = name; engine.rebuildFxChains(); touched() }
@@ -902,7 +902,7 @@ class AppViewModel(
}
/** Import a preset from picked bytes: a `.zip` bundle (Sampler) or plain text. */
fun importPreset(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, bytes: ByteArray): Boolean {
fun importPreset(slot: space.rcmd.android.sizzle.model.ToolboxSlot, bytes: ByteArray): Boolean {
val isZip = bytes.size >= 2 && bytes[0] == 'P'.code.toByte() && bytes[1] == 'K'.code.toByte()
val ok = if (isZip) presetLibrary.importZip(slot, java.io.ByteArrayInputStream(bytes))
else presetLibrary.importText(slot, String(bytes, Charsets.UTF_8))
@@ -911,11 +911,11 @@ class AppViewModel(
}
/** A shareable file for a stored preset (a zip bundle for the Sampler). */
fun presetShareFile(type: com.reactorcoremeltdown.sizzletracker.model.ToolboxType, name: String): java.io.File? =
fun presetShareFile(type: space.rcmd.android.sizzle.model.ToolboxType, name: String): java.io.File? =
presetLibrary.bundleForShare(type, name)
/** Delete a stored preset (and, for the Sampler, its bundled sample). */
fun deletePreset(type: com.reactorcoremeltdown.sizzletracker.model.ToolboxType, name: String): Boolean {
fun deletePreset(type: space.rcmd.android.sizzle.model.ToolboxType, name: String): Boolean {
val ok = presetLibrary.delete(type, name)
if (ok) touched()
return ok

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui
package space.rcmd.android.sizzle.ui
import android.content.res.Configuration
import androidx.compose.runtime.Composable

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui
package space.rcmd.android.sizzle.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
@@ -26,11 +26,11 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.Pitch
import com.reactorcoremeltdown.sizzletracker.ui.components.PianoKey
import com.reactorcoremeltdown.sizzletracker.ui.components.PianoOctave
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.Pitch
import space.rcmd.android.sizzle.ui.components.PianoKey
import space.rcmd.android.sizzle.ui.components.PianoOctave
import space.rcmd.android.sizzle.ui.components.RetroButton
import space.rcmd.android.sizzle.ui.theme.LocalRetro
private const val VEL_STEP = 8

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.components
package space.rcmd.android.sizzle.ui.components
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextMeasurer

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.components
package space.rcmd.android.sizzle.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -23,7 +23,7 @@ import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* Lays out one octave as a real piano keyboard: seven white keys across the bottom

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.components
package space.rcmd.android.sizzle.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -26,7 +26,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* A tiny library of "pixel" UI building blocks. They are intentionally plain

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.mixer
package space.rcmd.android.sizzle.ui.mixer
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
@@ -34,15 +34,15 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.Mixer
import com.reactorcoremeltdown.sizzletracker.model.MixerChannel
import com.reactorcoremeltdown.sizzletracker.model.ToolboxKind
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.isLandscape
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.components.SectionLabel
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.Mixer
import space.rcmd.android.sizzle.model.MixerChannel
import space.rcmd.android.sizzle.model.ToolboxKind
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.isLandscape
import space.rcmd.android.sizzle.ui.components.RetroButton
import space.rcmd.android.sizzle.ui.components.RetroDropdown
import space.rcmd.android.sizzle.ui.components.SectionLabel
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* The second tab: a four-channel mixer, one strip per tracker track. Each strip

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.settings
package space.rcmd.android.sizzle.ui.settings
import android.content.Context
import android.content.Intent
@@ -60,10 +60,10 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.core.content.FileProvider
import com.reactorcoremeltdown.sizzletracker.input.GamepadChord
import com.reactorcoremeltdown.sizzletracker.input.GamepadInput
import com.reactorcoremeltdown.sizzletracker.input.InputSource
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import space.rcmd.android.sizzle.input.GamepadChord
import space.rcmd.android.sizzle.input.GamepadInput
import space.rcmd.android.sizzle.input.InputSource
import space.rcmd.android.sizzle.ui.AppViewModel
/**
* The fourth tab, built from STANDARD Material 3 components (Cards, Buttons,

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.theme
package space.rcmd.android.sizzle.ui.theme
import android.app.Activity
import androidx.compose.foundation.isSystemInDarkTheme

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox
package space.rcmd.android.sizzle.ui.toolbox
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
@@ -25,11 +25,11 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.DelayDivisions
import com.reactorcoremeltdown.sizzletracker.model.ParamSpec
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.DelayDivisions
import space.rcmd.android.sizzle.model.ParamSpec
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* The Tape Delay's custom editor: four tape heads side by side, each a vertical

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox
package space.rcmd.android.sizzle.ui.toolbox
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -13,10 +13,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.components.RetroDropdown
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* A modulation target: a numeric parameter on another device the LFO can drive.

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox
package space.rcmd.android.sizzle.ui.toolbox
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -13,11 +13,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.ParamSpec
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.ParamSpec
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.components.RetroDropdown
import space.rcmd.android.sizzle.ui.theme.LocalRetro
import kotlin.math.roundToInt
/**

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox
package space.rcmd.android.sizzle.ui.toolbox
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
@@ -37,13 +37,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.audio.SampleStore
import com.reactorcoremeltdown.sizzletracker.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.SamplerPads
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.audio.SampleStore
import space.rcmd.android.sizzle.model.Pitch
import space.rcmd.android.sizzle.model.SamplerPads
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.components.RetroButton
import space.rcmd.android.sizzle.ui.theme.LocalRetro
import kotlin.math.abs
/**

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox
package space.rcmd.android.sizzle.ui.toolbox
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
@@ -38,20 +38,20 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.audio.SampleStore
import com.reactorcoremeltdown.sizzletracker.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.PianoKey
import com.reactorcoremeltdown.sizzletracker.ui.components.PianoOctave
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.audio.SampleStore
import space.rcmd.android.sizzle.model.Pitch
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.components.PianoKey
import space.rcmd.android.sizzle.ui.components.PianoOctave
import space.rcmd.android.sizzle.ui.components.RetroButton
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* The SoundFont device editor: load an `.sf2` / `.xi` (or `.wav`) file from local
* storage, preview its waveform, set output volume, and audition it pitched across
* a two-octave keyboard. The extracted sample plays across the whole keyboard from
* the file's root note (see [com.reactorcoremeltdown.sizzletracker.audio.SoundFontLoader]).
* the file's root note (see [space.rcmd.android.sizzle.audio.SoundFontLoader]).
*/
@Composable
fun SoundFontEditor(vm: AppViewModel, slot: ToolboxSlot) {

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox
package space.rcmd.android.sizzle.ui.toolbox
import android.content.Intent
import androidx.activity.compose.BackHandler
@@ -54,14 +54,14 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.FileProvider
import com.reactorcoremeltdown.sizzletracker.model.ParamSpec
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.isLandscape
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.ParamSpec
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.model.ToolboxType
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.isLandscape
import space.rcmd.android.sizzle.ui.components.RetroButton
import space.rcmd.android.sizzle.ui.components.RetroDropdown
import space.rcmd.android.sizzle.ui.theme.LocalRetro
import kotlinx.coroutines.launch
/**
@@ -104,7 +104,7 @@ fun ToolboxScreen(vm: AppViewModel) {
ToolboxTileGrid(vm, selected, onTapTile, onDoubleTapTile, onLongPressTile,
Modifier.weight(1f).fillMaxHeight())
Box(Modifier.width(2.dp).fillMaxHeight().background(c.accent))
com.reactorcoremeltdown.sizzletracker.ui.StackedKeyboard(vm, punchIn = false, Modifier.weight(1.3f))
space.rcmd.android.sizzle.ui.StackedKeyboard(vm, punchIn = false, Modifier.weight(1.3f))
}
} else {
// Portrait: a scrolling grid of square tiles above the keyboard (1.7 : 1).
@@ -126,7 +126,7 @@ fun ToolboxScreen(vm: AppViewModel) {
}
}
Box(Modifier.fillMaxWidth().height(2.dp).background(c.accent)) // fixed divider
com.reactorcoremeltdown.sizzletracker.ui.StackedKeyboard(vm, punchIn = false, Modifier.weight(1f))
space.rcmd.android.sizzle.ui.StackedKeyboard(vm, punchIn = false, Modifier.weight(1f))
}
}
@@ -373,7 +373,7 @@ private val AMBIENCE_SECTIONS = listOf(
* the presets saved for this device type, plus Save (to the app's on-disk preset
* library), Import (from a picked text preset or for the Sampler a `.zip`
* bundle), and Share (via the system share sheet). Presets are the plain-text
* [com.reactorcoremeltdown.sizzletracker.io.PresetIo] format, stored one folder
* [space.rcmd.android.sizzle.io.PresetIo] format, stored one folder
* per instrument/effect.
*/
@Composable

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.tracker
package space.rcmd.android.sizzle.ui.tracker
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
@@ -42,12 +42,12 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.Arrangement as ArrModel
import com.reactorcoremeltdown.sizzletracker.model.LoopRegion
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.GlyphCache
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.Arrangement as ArrModel
import space.rcmd.android.sizzle.model.LoopRegion
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.components.GlyphCache
import space.rcmd.android.sizzle.ui.components.RetroButton
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* The lower-half arrangement. Layout (spreadsheet-style, like the sizzletracker

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.tracker
package space.rcmd.android.sizzle.ui.tracker
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
@@ -23,13 +23,13 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.Cell
import com.reactorcoremeltdown.sizzletracker.model.CellColumn
import com.reactorcoremeltdown.sizzletracker.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Pitch
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.GlyphCache
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.Cell
import space.rcmd.android.sizzle.model.CellColumn
import space.rcmd.android.sizzle.model.Pattern
import space.rcmd.android.sizzle.model.Pitch
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.components.GlyphCache
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* The demoscene pattern grid, drawn as ONE [Canvas] instead of a tree of ~180

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.tracker
package space.rcmd.android.sizzle.ui.tracker
import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll
@@ -28,12 +28,12 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.isLandscape
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro
import space.rcmd.android.sizzle.model.TimeSignature
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.isLandscape
import space.rcmd.android.sizzle.ui.components.RetroButton
import space.rcmd.android.sizzle.ui.components.RetroDropdown
import space.rcmd.android.sizzle.ui.theme.LocalRetro
/**
* The first tab. Two stacked halves:
@@ -54,7 +54,7 @@ fun TrackerScreen(vm: AppViewModel) {
private fun TrackerLower(vm: AppViewModel, modifier: Modifier) {
Box(modifier) {
if (vm.punchInMode) {
com.reactorcoremeltdown.sizzletracker.ui.StackedKeyboard(vm, punchIn = true, Modifier.fillMaxSize())
space.rcmd.android.sizzle.ui.StackedKeyboard(vm, punchIn = true, Modifier.fillMaxSize())
} else {
ArrangementRoll(vm)
}
@@ -188,7 +188,7 @@ private fun PatternButtons(vm: AppViewModel) {
)
RetroDropdown(
label = "SCALE",
options = com.reactorcoremeltdown.sizzletracker.model.Scale.entries,
options = space.rcmd.android.sizzle.model.Scale.entries,
selected = project.scale,
optionLabel = { it.label },
onSelect = { project.scale = it; vm.bumpForToolbar() },
@@ -197,7 +197,7 @@ private fun PatternButtons(vm: AppViewModel) {
label = "ROOT",
options = (0..11).toList(),
selected = project.rootNote,
optionLabel = { com.reactorcoremeltdown.sizzletracker.model.Pitch.name(60 + it).dropLast(1) },
optionLabel = { space.rcmd.android.sizzle.model.Pitch.name(60 + it).dropLast(1) },
onSelect = { project.rootNote = it; vm.bumpForToolbar() },
)
}

View File

@@ -1,12 +1,12 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io
package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.Arrangement
import com.reactorcoremeltdown.sizzletracker.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.Project
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature
import space.rcmd.android.sizzle.model.Arrangement
import space.rcmd.android.sizzle.model.Pitch
import space.rcmd.android.sizzle.model.Project
import space.rcmd.android.sizzle.model.TimeSignature
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertTrue

View File

@@ -84,7 +84,7 @@ Three ideas hold it together:
## 4. Package/file map
```
com.reactorcoremeltdown.sizzletracker
space.rcmd.android.sizzle
├── SizzleApp.kt Application = tiny DI container (Project, InputRouter, AudioEngine)
├── MainActivity.kt Hosts Compose UI; forwards HW key/motion events; starts MIDI + service