jam-cloud/.planning/codebase/JAMTRACK_API.md

14 KiB

JamTrack jamClient API Reference

Complete reference for jamClient JamTrack-related methods discovered in web/app/assets/javascripts/bridge_api.es6 and usage patterns from legacy code.

Source: Lines 1035-1093 in bridge_api.es6

1. Playback Methods

JamTrackPlay(fqId)

Purpose: Load JamTrack into session (despite name, this is "load", not "play")

Signature:

context.jamClient.JamTrackPlay(fqId)

Parameters:

  • fqId (string): Fully-qualified ID format: {jamTrackId}-{sampleRate}
    • Example: '12345-48' or '12345-44'
    • Sample rate: '44' for 44.1kHz, '48' for 48kHz
    • Must match client's audio sample rate (from GetSampleRate())

Returns: Boolean

  • true: JamTrack loaded successfully
  • false: Failed to load (show error to user)

Usage pattern (session.js:2760):

var sampleRate = context.jamClient.GetSampleRate(); // 44 or 48
var sampleRateForFilename = sampleRate == 48 ? '48' : '44';
var fqId = jamTrack.id + '-' + sampleRateForFilename;

var result = context.jamClient.JamTrackPlay(fqId);
if (!result) {
  app.notify({
    title: "JamTrack Can Not Open",
    text: "Unable to open your JamTrack. Please contact support@jamkazam.com"
  }, null, true);
}

Notes:

  • Must be called AFTER JamTrack is synchronized (on disk with keys)
  • Loads all stem tracks into session mixer
  • Call JamTrackLoadJmep(fqId, jmepData) BEFORE this if tempo/pitch modifications needed

JamTrackStopPlay()

Purpose: Stop JamTrack playback and unload from session

Signature:

context.jamClient.JamTrackStopPlay()

Parameters: None

Returns: Void

Usage pattern (session.js:2743):

// Always stop before loading new JamTrack
context.jamClient.JamTrackStopPlay();

Notes:

  • Cleans up current JamTrack resources
  • Should be called before loading a new JamTrack
  • Safe to call even if no JamTrack is loaded

JamTrackIsPlaying()

Purpose: Query whether a JamTrack is currently playing

Signature:

context.jamClient.JamTrackIsPlaying()

Parameters: None

Returns: Boolean

  • true: JamTrack is actively playing
  • false: No JamTrack playing or paused

Notes:

  • Use for playback state checks in UI
  • Similar to isSessionTrackPlaying() for Backing Tracks

JamTrackIsPlayable()

Purpose: Check if JamTrack can be played (loaded and ready)

Signature:

context.jamClient.JamTrackIsPlayable()

Parameters: None

Returns: Boolean

  • true: JamTrack is loaded and can be played
  • false: No JamTrack loaded or not ready

Notes:

  • Use to enable/disable play button
  • Checks if JamTrack was successfully loaded via JamTrackPlay()

2. Track Data Methods

JamTrackGetTracks()

Purpose: Get list of stem tracks in currently loaded JamTrack

Signature:

context.jamClient.JamTrackGetTracks()

Parameters: None

Returns: Array of track objects (format TBD - not shown in legacy code)

Notes:

  • Called after JamTrack is loaded
  • Returns individual stems (drums, bass, guitar, vocals, etc.)
  • Used to populate stem mixer UI

JamTrackGetTrackDetail(fqId)

Purpose: Get synchronization state and version for a JamTrack

Signature:

context.jamClient.JamTrackGetTrackDetail(fqId)

Parameters:

  • fqId (string): Fully-qualified ID {jamTrackId}-{sampleRate}

Returns: Object

{
  key_state: string,  // Encryption key status
  version: number     // JamTrack version number
}

Usage pattern (download_jamtrack.js.coffee state machine):

  • Queries client to determine current sync state
  • Used by state machine to decide next action (packaging, downloading, keying, synchronized)
  • key_state values determine if encryption keys are available

Notes:

  • Called repeatedly during download/sync process
  • Return value drives state machine transitions
  • Critical for determining when JamTrack is ready to play

JamTrackGetImage()

Purpose: Get album art image for currently loaded JamTrack

Signature:

context.jamClient.JamTrackGetImage()

Parameters: None

Returns: Image data (format TBD - possibly base64 or file path)

Notes:

  • Display album art in player UI
  • Similar functionality to potential Backing Track cover art

GetJamTrackTimeline()

Purpose: Get timeline/waveform data for visualization

Signature:

context.jamClient.GetJamTrackTimeline()

Parameters: None

Returns: Timeline data structure (format TBD)

Notes:

  • Used for waveform visualization in UI
  • May include beat markers, section markers
  • Advanced feature for timeline scrubbing

3. Download/Sync Methods

JamTrackDownload(jamTrackId, mixdownId, userId, progressCallback, successCallback, failCallback)

Purpose: Download JamTrack package from server to local disk

Signature:

context.jamClient.JamTrackDownload(
  jamTrackId,         // JamTrack ID (integer)
  mixdownId,          // Selected mixdown package ID (integer)
  userId,             // Current user ID (integer)
  progressCallback,   // Function name (string) for progress updates
  successCallback,    // Function name (string) for completion
  failCallback        // Function name (string) for errors
)

Parameters:

  • All parameters required
  • Callbacks are function names as strings, not function references
  • Callbacks are called by native client with download progress data

Returns: Void (callbacks handle results)

Usage pattern (download_jamtrack.js.coffee downloading state):

context.jamClient.JamTrackDownload(
  @jamTrack.id,
  @jamTrack.selectedMixdown.id,
  @app.currentUser.id,
  'onDownloadProgress',  # String, not function ref
  'onDownloadSuccess',
  'onDownloadFail'
)

Callback signatures:

  • progressCallback(percentComplete, bytesDownloaded, totalBytes)
  • successCallback()
  • failCallback(errorMessage)

Notes:

  • Called when state machine reaches downloading state
  • Must be preceded by mixdown packaging on server
  • After success, call JamTrackKeysRequest() to fetch encryption keys
  • Callbacks must be global functions accessible to native client

JamTrackKeysRequest()

Purpose: Request encryption keys for downloaded JamTrack

Signature:

context.jamClient.JamTrackKeysRequest()

Parameters: None

Returns: Void (asynchronous operation)

Usage pattern (download_jamtrack.js.coffee keying state):

  • Called after successful download
  • Native client fetches keys from server
  • Poll JamTrackGetTrackDetail() to check when keys are available
  • State machine has 10-second timeout for keying operation

Notes:

  • Required for encrypted JamTrack playback
  • Separate step from download
  • Can fail with timeout if server doesn't respond
  • After success, JamTrack is "synchronized" and ready to play

InvalidateJamTrack(fqId)

Purpose: Clear cached JamTrack version, force re-download

Signature:

context.jamClient.InvalidateJamTrack(fqId)

Parameters:

  • fqId (string): Fully-qualified ID {jamTrackId}-{sampleRate}

Returns: Void

Notes:

  • Used when new JamTrack version is available
  • Forces download of updated package
  • Clears local cache and encryption keys

4. JMEP (Jam Enhancement Package) Methods

JamTrackLoadJmep(fqId, jmepData)

Purpose: Load tempo/pitch modifications for JamTrack playback

Signature:

context.jamClient.JamTrackLoadJmep(fqId, jmepData)

Parameters:

  • fqId (string): Fully-qualified ID {jamTrackId}-{sampleRate}
  • jmepData (object): JMEP data structure with tempo/pitch settings

Returns: Void

Usage pattern (session.js:2749-2757):

if(jamTrack.jmep) {
  logger.debug("setting jmep data");
  context.jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep);
} else {
  logger.debug("no jmep data for jamtrack");
}

// Load JamTrack AFTER setting JMEP
context.jamClient.JamTrackPlay(fqId);

JMEP data structure:

{
  tempo: number,        // Tempo modification (BPM or percentage)
  pitch: number,        // Pitch shift (semitones)
  // Additional fields TBD
}

Notes:

  • Must be called BEFORE JamTrackPlay()
  • Optional feature - check if(jamTrack.jmep) before calling
  • Allows practicing at different tempos without re-encoding
  • Pitch shift for transposition to different keys

5. Playback Control Methods

SessionJamTrackSeekMs()

Purpose: Seek to specific position in JamTrack playback

Signature:

context.jamClient.SessionJamTrackSeekMs(positionMs)

Parameters:

  • positionMs (number): Position in milliseconds

Returns: Void (or boolean - TBD)

Notes:

  • Similar to SessionTrackSeekMs() for Backing Tracks
  • Use for seek bar / scrubbing functionality
  • Requires JamTrack to be loaded and playing/paused

SessionCurrrentJamTrackPlayPosMs()

Purpose: Get current playback position in milliseconds

Signature:

context.jamClient.SessionCurrrentJamTrackPlayPosMs()

Parameters: None

Returns: Number (milliseconds)

Notes:

  • Poll at 500ms intervals for playback monitoring
  • Similar to SessionCurrentPlayPosMs() for Backing Tracks
  • Use for time display and seek bar position
  • Returns string - use parseInt() before math operations

SessionGetJamTracksPlayDurationMs()

Purpose: Get total duration of loaded JamTrack in milliseconds

Signature:

context.jamClient.SessionGetJamTracksPlayDurationMs()

Parameters: None

Returns: Number (milliseconds)

Notes:

  • Note plural "JamTracks" in method name (differs from singular in other methods)
  • Call after JamTrack is loaded to get duration
  • Use for time display and seek bar maximum
  • Returns string - use parseInt() before math operations

6. Query Methods

GetSampleRate()

Purpose: Get audio interface sample rate (44.1 or 48 kHz)

Signature:

context.jamClient.GetSampleRate()

Parameters: None

Returns: Number

  • 44 for 44.1 kHz
  • 48 for 48 kHz

Usage pattern (session.js:2745):

var sampleRate = context.jamClient.GetSampleRate();
var sampleRateForFilename = sampleRate == 48 ? '48' : '44';
var fqId = jamTrack.id + '-' + sampleRateForFilename;

Notes:

  • Critical for fqId construction
  • Sample rate determined by user's audio interface configuration
  • JamTrack packages are encoded at specific sample rates
  • Must match package sample rate for playback

7. Comparison: JamTrack vs Backing Track Methods

Operation JamTrack Method Backing Track Method Notes
Select file jQuery dialog ShowSelectBackingTrackDialog() JamTrack: purchased list; Backing Track: native file picker
Open/Load JamTrackPlay(fqId) SessionOpenBackingTrackFile(path) JamTrack: ID-based; Backing Track: file path
Stop JamTrackStopPlay() SessionCloseBackingTrack(path) JamTrack: no params; Backing Track: needs path
Check playing JamTrackIsPlaying() isSessionTrackPlaying() Same concept
Get position SessionCurrrentJamTrackPlayPosMs() SessionCurrentPlayPosMs() Same concept
Get duration SessionGetJamTracksPlayDurationMs() SessionGetTracksPlayDurationMs() Both plural "Tracks"
Seek SessionJamTrackSeekMs(ms) SessionTrackSeekMs(ms) Same concept

Shared methods (used by both):

  • SessionStartPlay() - Start playback
  • SessionStopPlay() - Stop playback
  • SessionPausePlay() - Pause playback
  • GetSampleRate() - Audio interface sample rate

Key differences:

  1. Identification: JamTrack uses fqId (id-sampleRate), Backing Track uses file path
  2. Selection UI: JamTrack has server-side catalog, Backing Track is local files
  3. Synchronization: JamTrack requires download/keys, Backing Track is immediate
  4. Stems: JamTrack has multiple stem tracks, Backing Track is single file
  5. JMEP: JamTrack supports tempo/pitch modification, Backing Track does not

Usage Examples

Example 1: Complete JamTrack Load Flow

// 1. Get sample rate
const sampleRate = jamClient.GetSampleRate(); // 44 or 48
const sampleRateStr = sampleRate == 48 ? '48' : '44';
const fqId = `${jamTrack.id}-${sampleRateStr}`;

// 2. Stop any existing playback
jamClient.JamTrackStopPlay();

// 3. Load JMEP if present (tempo/pitch modifications)
if (jamTrack.jmep) {
  jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep);
}

// 4. Load JamTrack
const result = jamClient.JamTrackPlay(fqId);
if (!result) {
  console.error('Failed to load JamTrack');
  return;
}

// 5. Start playback
jamClient.SessionStartPlay();

Example 2: Download and Sync

// 1. Start download
jamClient.JamTrackDownload(
  jamTrackId,
  mixdownId,
  userId,
  'onProgress',  // Callback names as strings
  'onSuccess',
  'onFail'
);

// 2. On download success, request encryption keys
function onSuccess() {
  jamClient.JamTrackKeysRequest();

  // Poll for key availability
  const checkKeys = setInterval(() => {
    const detail = jamClient.JamTrackGetTrackDetail(fqId);
    if (detail.key_state === 'AVAILABLE') {
      clearInterval(checkKeys);
      // Now can call JamTrackPlay(fqId)
    }
  }, 500);
}

Example 3: Playback Monitoring

// Poll every 500ms for position updates
const pollInterval = setInterval(async () => {
  if (!jamClient.JamTrackIsPlaying()) {
    clearInterval(pollInterval);
    return;
  }

  const position = parseInt(jamClient.SessionCurrrentJamTrackPlayPosMs());
  const duration = parseInt(jamClient.SessionGetJamTracksPlayDurationMs());

  updateUI(position, duration);
}, 500);

Critical Notes for React Implementation

  1. fqId format is mandatory: Always {jamTrackId}-{sampleRate}
  2. Sample rate matters: Must match package sample rate (44 or 48)
  3. Load order: JMEP → JamTrackPlay → SessionStartPlay
  4. String returns: All position/duration methods return strings, use parseInt()
  5. Async operations: Download and key fetching are asynchronous with callbacks
  6. Callback names: Pass callback names as strings, not function references
  7. Global scope: Callback functions must be accessible globally to native client
  8. Shared playback controls: Use Session* methods (Start/Stop/Pause) like Backing Track

Method Availability

All methods assume native client is available (gon.isNativeClient === true). In browser mode, show appropriate fallback UI directing users to download the native client.