This is a chiptune tracker app with shared C++ core logic and platform-specific UI layers.
What it is: A music tracker application for creating Commodore 64-style chiptune music using SID chip emulation.
Platforms:
- Linux desktop (primary development platform)
- Android (published on Play Store)
Architecture: C++ core with platform-specific UI layers
- Desktop: SDL2 + OpenGL
- Android: GLSurfaceView + JNI bridge to C++
src/ # Shared C++ source code
└── *.cpp/*.hpp # Core tracker logic
android/ # Android app project
├── app/
│ ├── src/main/
│ │ ├── cpp/ # Shared C++ source (same as src/, JNI glue in main.cpp)
│ │ ├── java/ # Java activity and view classes
│ │ └── res/ # Android resources
│ └── build.gradle.kts
lib/ # Third-party dependencies (glm, libsndfile)
docs/ # User documentation
- Build tool: CMake
- Dependencies: GLEW, SDL2, libsndfile (found via pkg-config)
- Build command:
mkdir build && cd build && cmake .. && make - Output:
build/fakesidexecutable
- Build tool: Gradle with Kotlin DSL
- Native build: CMake (invoked by Gradle)
- Dependencies:
com.google.oboe:oboe- Audio outputlibsndfile- Bundled inlib/folder
- Build: Open
android/in Android Studio or./gradlew assembleDebug - Key files:
android/app/build.gradle.kts- App build configandroid/app/src/main/CMakeLists.txt- Native C++ buildandroid/gradle/libs.versions.toml- Dependency versions
- main.cpp - Entry point (desktop) or JNI initialization (Android)
- sid_engine.cpp - SID chip emulation (based on kb's TinySID)
- player.cpp - Music playback engine
- song.cpp/song.hpp - Song data structures
- gui.cpp - Main UI logic
- gfx.cpp - OpenGL rendering
- app.cpp, edit.cpp, settings.cpp - Various app features
- *_view.cpp - Different UI screens (track, song, project, jam, instrument effect)
- resid-0.16/ - Removed - using custom SID emulation based on kb's TinySID
- MainActivity.java - Activity lifecycle, permissions, keyboard control
- MainView.java - GLSurfaceView wrapper, touch input handling
- Lib.java - JNI native method declarations
The Java layer calls into C++ via these native methods (defined in Lib.java):
init(AssetManager, String storageDir)- Initialize C++ with Android assets and storage directoryresize(int, int)- Handle surface resizedraw()- Render OpenGL frametouch(int, int, int)- Forward touch events to C++key(int, int)- Forward key events to C++startAudio()/stopAudio()- Audio lifecyclesetInsets(int, int)- Handle system insets (status bar, navigation bar)getSettingName(int)/getSettingValue(int)/setSettingValue(int, int)- Settings managementimportSong(String path)- Import song from SAF-provided path or intentexportSong(String path, String title)- Export song via FileProvider (unused in current implementation)
- Desktop: Uses SDL2 audio
- Android: Uses Oboe library for low-latency audio
- Audio runs on separate thread, coordinated by C++ layer
- Both platforms use OpenGL (desktop: full GL, Android: ES 2)
stb_image.his used for texture loading- Custom immediate-mode style UI in
gfx.cpp
- Desktop: Direct file I/O using libsndfile
- Android: Storage Access Framework (SAF) - fully implemented
- Storage Location:
getExternalFilesDir()- app-specific storage - Song Import:
- Via IMPORT button: SAF file picker → copies to cache → loads into app
- From other apps: WhatsApp/email → intent → cache → loads into app
- Song Export: SAVE AS button → saves to app storage → FileProvider share intent → user chooses destination
- WAV/OGG Export: Renders to app storage → FileProvider share intent → user chooses destination
- No permissions required - Uses SAF for all user-facing file operations
- FileProvider configured in
AndroidManifest.xmlwithres/xml/file_paths.xml - Intent filters: ACTION_VIEW and ACTION_SEND to open files from other apps
- Storage Location:
- sid_engine: SID chip emulation (based on kb's TinySID)
- libsndfile: Sound file I/O (WAV/OGG output)
- glm: Math library (header-only)
- oboe: Android audio (low-latency audio output)
mkdir -p build && cd build
cmake ..
make
./fakesidcd android
./gradlew assembleDebug
# Or open in Android Studio and click "Run"- For desktop: Add to CMakeLists.txt
pkg_search_module() - For Android: Add to
android/app/build.gradle.ktsor use Prefab (if available) - Update both
CMakeLists.txtfiles if needed
- Check
MainActivity.javaandLib.javafor method signatures - JNI implementations are in C++ files (look for
Java_com_twobit_fakesid_...functions) - Use
adb logcatto see native crashes
- No CI/CD - Manual builds only
- Storage Access Framework (SAF) - No storage permissions, modern file handling
- IMPORT button - Load songs from anywhere (Downloads, Drive, etc.)
- SAVE AS button - Export song files to any location
- Open from other apps - Receive
.sngfiles from WhatsApp, email, etc. - Updated to targetSdk/compileSdk 36 - Android 14 compatibility
- Java 17 - Build compatibility