SonicSyncSail Logo

SonicSyncSail

Home Features About Blog FAQ

Pulse Editor

Complete developer and user documentation for the Pulse Editor feature in SonicSyncSail. This page describes UI behavior, data flow, implementation notes, integration with playback components and known limitations.

Table of contents
1. Overview 2. Editor Sections (Info, Clipper, Settings, Available) 3. Pulse Clipper — Slider & Waveform 4. Selection Controls & Playback Behaviour 5. Pulse Settings: Emotion & Intensity 6. Data Flow & Persistence 7. Playback Integration (Media3 / ExoPlayer) 8. Waveform generation (MP3 / downsampled PCM) 9. Implementation Notes & API samples 10. Edge cases, limitations & safeguards 11. Accessibility & UX considerations 12. Testing & QA checklist 13. Appendix: DB schema, JSON examples

1. Overview

The Pulse Editor enables users to select, annotate and save short timestamped audio segments ("pulses") inside songs. These pulses are associated with emotion tags and intensity levels and can be mixed later by the PulseSync mixer to produce a continuous, emotionally curated playback experience.

Primary goals:

  • Allow precise start/end selection for memorable moments inside tracks.
  • Capture user-chosen emotion tags and intensity metadata for each segment.
  • Provide both quick (slider) and precise (waveform) selection modes.
  • Offer immediate preview looping to audition and refine selections.
2. Editor Sections

Info Section

Displays current song metadata: album art, title and duration. Also includes:

  • A Toggle that determines whether creating a pulse segment is currently enabled.
  • A New Segment button that resets the editor state to defaults (creates a fresh editing session).

Pulse Clipper Section

Primary editing canvas where users define start and end timestamps and preview playback in a loop. Two selection methods are available: Slider view (default) and Waveform view (advanced, with auto intensity detection).

Pulse Settings Section

Emotion category chips, derived emotion tags, and an emotion intensity control (Low / Medium / High). The section contains these primary controls:

  • Emotion category selection (e.g., Positive, Romantic, Chill).
  • Emotion-tag chips specific to selected category (one required before saving).
  • Intensity slider — auto-detected in waveform mode; manual in slider mode.
  • Save Segment button (enabled only when the selection or settings change).

Available Segments Section

Lists saved segments for the loaded song. Features:

  • Cards for each saved segment with a delete icon.
  • Clicking a card loads it into the editor in update mode.
  • "Delete All" to remove all segments for the current song (confirmation dialog required).
3. Pulse Clipper — Slider & Waveform

A. Slider View (default)

Uses Material3 double-handle slider. Behavior notes:

  • Handles set start and end timestamps independently.
  • Quick to use for coarse selection; does not provide auto emotion intensity detection.
  • Supports precise adjustments through the selection controls row (see section 4).

B. Waveform View (advanced)

Generates a downsampled PCM waveform for the loaded MP3 file and overlays draggable handles. Behavior notes:

  • Waveform generation is done on-device from downsampled PCM extracted from MP3 files only.
  • When waveform generation completes, an auto emotion intensity is computed using a lightweight DSP analysis (bpm estimate, short-time energy and dynamic range heuristics).
  • Users may drag either handle individually or adjust the whole selection by dragging the middle overlay.
4. Selection Controls & Playback Behavior

Common controls present below both Slider and Waveform modes:

  1. Six directional buttons for fine adjustments: >> << <-- --> >> << (representing incremental single-second shifts of left / right handles and entire selection).
  2. Long-press on those buttons triggers repeated fast adjustments appropriate to the control (e.g., continuous left-shift).
  3. A selection progress bar for seeking within the preview loop and convenient auditioning of large segments.
  4. Start/end timestamp labels at each end of the progress bar.
  5. Play/Pause preview button: plays only the selection range, loops back to start timestamp when end is reached. Any timestamp adjustment resets preview to start time.

Looping behavior: The preview loop always restarts at the start timestamp. Adjusting timestamps while the preview is playing causes the playhead to reposition to the new start time and continue looping (until pause).

5. Pulse Settings: Emotion & Intensity

Structure and validation:

  • Top-level emotion categories are presented as chips (single-select).
  • Category selection reveals a row of emotion-tag chips (one must be selected before Save).
  • Intensity control: three-staged value (Low, Medium, High). In waveform mode intensity is auto-detected, but the slider remains editable.

Why intensity matters: Intensity provides a compact representation of pulse energy (bpm proxy, loudness and transient activity). The PulseMixer uses intensity to prefer smoother transitions between segments by selecting pulses with matching intensity for consecutive mixes.

Button state rules:

  • Save Segment is disabled until the editor detects at least one change in timestamps or settings.
  • If the loaded item is an existing segment, the action becomes Update Segment and follows the same enablement rules.
6. Data Flow & Persistence

Primary storage is a Room database table that holds metadata for each pulse segment. The app also mirrors essential metadata inside MediaStore / local caches for fast lookup.

Pulse Segment Entity (Room)

@Entity(tableName = "pulse_segments")
data class PulseSegment(
  @PrimaryKey val id: String,
  val trackId: String,            // id that links to MediaStore / app track entity
  val startMs: Long,
  val endMs: Long,
  val category: String,
  val tag: String,
  val intensity: String,          // "low" | "medium" | "high"
  val createdAt: Long,
  val updatedAt: Long
)

When the user saves a segment:

  1. Validate selection (start < end, minimum duration threshold if any).
  2. Persist the row in Room.
  3. Update the in-memory cache and UI lists (Available Segments).
  4. Emit an analytics event (Firebase) and persist undo history if implemented.
7. Playback Integration (Media3 / ExoPlayer)

The preview player and PulseMixer rely on Media3 (ExoPlayer) with ClippingMediaSource to play exact timestamped regions.

Preview Loop Player

  • Construct a clipped media source for the selected start/end timestamps so playback begins precisely at startMs and ends at endMs.
  • Use ExoPlayer loop mode or listen for completion and seek back to startMs to loop without gaps.
  • On timestamp change, stop the player, re-create the clipped source with new bounds and resume looped preview if the user was playing.

PulseMixer (runtime stitching)

When Sync Mode is active, the mixer builds a playlist of clipped sources (one per saved pulse). Between clips the mixer applies:

  • Short crossfades at boundaries.
  • A basic tempo/beat alignment pass (beatmatching heuristics) to reduce perceptual artifacts at transitions.
8. Waveform generation (MP3 / downsampled PCM)

Waveform generation is explicitly supported for MP3 files only. Implementation notes:

  • Decode a short, downsampled PCM stream (e.g., 8k–22k sample rate) on a background thread to compute amplitude envelopes.
  • Aggregate frames into buckets to produce waveform points suitable for on-screen rendering.
  • Run a lightweight DSP analysis to estimate RMS/energy and a BPM proxy for emotion intensity.
  • The process is CPU-bound; limit waveform generation to the currently loaded track and cancel generation if user navigates away.

Important: Waveform generation does not run for non-MP3 formats — gracefully fall back to the slider view and surface a message explaining the limitation to users.

9. Implementation Notes & API samples

Concurrency & threading

Waveform generation and DSP analyses must run on a worker thread (Coroutines + Dispatchers.Default). UI updates should be dispatched to the Main thread.

Sample: create clipped playable (Kotlin / Media3)

// Pseudocode
val mediaItem = MediaItem.fromUri(trackUri)
val player = ExoPlayer.Builder(context).build()
val dataSourceFactory = DefaultDataSource.Factory(context)
val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
  .createMediaSource(mediaItem)
val clipped = ClippingMediaSource(mediaSource, startMs * 1000, endMs * 1000)
player.setMediaSource(clipped)
player.prepare()
player.play()

Undo / Safe save

When updating an existing segment, keep a lightweight undo buffer so users can revert accidental changes (optional enhancement).

10. Edge cases, limitations & safeguards
  • Non-MP3 formats: Waveform + auto intensity detection disabled; slider remains available.
  • Very short segments: Enforce a configurable minimum duration to avoid unusable pulses (e.g., <500ms).
  • Large selections: Provide a clear UI to jump inside the selection via the selection progress bar.
  • Permission denial: Tag the editor as read-only and surface the permissions dialog workflow.
  • Device resource limits: Cancel waveform generation on low-memory or when CPU is constrained; degrade gracefully.
11. Accessibility & UX considerations
  • Provide large tap targets for handles and control buttons.
  • Expose keyboard and external controller accessibility for precise adjustments where possible.
  • Offer haptic feedback on handle drag start/stop and on long-press accelerated adjustments.
  • Use clear ARIA-like content descriptions for screen readers (Android TalkBack): report start/end times, current intensity and selected tag.
12. Testing & QA checklist
  1. Waveform generation completes for MP3s and cancels on navigation away.
  2. Slider and waveform handles produce identical start/end values for the same position.
  3. Preview loop is gapless and restarts at startMs consistently.
  4. Save / Update persist to Room and reflected immediately in Available Segments list.
  5. Long-press adjustment repeats correctly and stops when released.
  6. PulseMixer uses intensity to prefer smoother transitions (QA with test mixes).
13. Appendix: DB schema, JSON examples

Suggested Room indices

  • Index on trackId to quickly fetch pulses for a given track.
  • Index on category if category-based retrieval becomes frequent.

Documentation generated for Dhana — review and request adjustments. Once approved I will align styles precisely to the Tag Editor page and can provide example component code for the editor UI.

© SonicSyncSail 2025 · v1.0
GitHub🐙 GitHub GitHub🔗 LinkedIn 📧 contact@sonicsyncsail.com Privacy Policy Terms & Conditions