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:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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:
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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]
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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].
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
@@ -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(
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 —
|
||||
@@ -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
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
@@ -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) {
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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() },
|
||||
)
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
│
|
||||
|
||||
Reference in New Issue
Block a user