docs(04-01): create jamClient JamTrack API reference

- Documented all 15+ JamTrack-specific jamClient methods with signatures
- Covered playback, track data, download/sync, and JMEP methods
- Added comparison table: JamTrack vs Backing Track methods
- Included usage examples for load flow, download/sync, monitoring
- Noted critical implementation details (fqId format, async patterns, string returns)
This commit is contained in:
Nuwan 2026-01-14 21:20:46 +05:30
parent b7208d945c
commit d3ff1f1477
1 changed files with 569 additions and 0 deletions

View File

@ -0,0 +1,569 @@
# 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:**
```javascript
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):
```javascript
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:**
```javascript
context.jamClient.JamTrackStopPlay()
```
**Parameters:** None
**Returns:** Void
**Usage pattern** (session.js:2743):
```javascript
// 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:**
```javascript
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:**
```javascript
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:**
```javascript
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:**
```javascript
context.jamClient.JamTrackGetTrackDetail(fqId)
```
**Parameters:**
- `fqId` (string): Fully-qualified ID `{jamTrackId}-{sampleRate}`
**Returns:** Object
```javascript
{
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:**
```javascript
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:**
```javascript
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:**
```javascript
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):
```coffeescript
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:**
```javascript
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:**
```javascript
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:**
```javascript
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):
```javascript
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:**
```javascript
{
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:**
```javascript
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:**
```javascript
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:**
```javascript
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:**
```javascript
context.jamClient.GetSampleRate()
```
**Parameters:** None
**Returns:** Number
- `44` for 44.1 kHz
- `48` for 48 kHz
**Usage pattern** (session.js:2745):
```javascript
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
```javascript
// 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
```javascript
// 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
```javascript
// 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.