PebbleOS
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions

Now-playing metadata cache and media control. More...

Data Structures

struct  MusicServerImplementation
 Operations implemented by a music backend. More...
 
struct  MusicPlayerStateUpdate
 Playback state update. More...
 

Macros

#define MUSIC_BUFFER_LENGTH   64
 Size of the string buffers used for metadata, including the terminator.
 

Enumerations

enum  MusicPlayState {
  MusicPlayStateUnknown , MusicPlayStatePlaying , MusicPlayStatePaused , MusicPlayStateForwarding ,
  MusicPlayStateRewinding , MusicPlayStateInvalid = 0xFF
}
 Playback state of the player. More...
 
enum  MusicCommand {
  MusicCommandPlay , MusicCommandPause , MusicCommandTogglePlayPause , MusicCommandNextTrack ,
  MusicCommandPreviousTrack , MusicCommandVolumeUp , MusicCommandVolumeDown , MusicCommandAdvanceRepeatMode ,
  MusicCommandAdvanceShuffleMode , MusicCommandSkipForward , MusicCommandSkipBackward , MusicCommandLike ,
  MusicCommandDislike , MusicCommandBookmark , NumMusicCommand
}
 Control command sent to the player. More...
 
enum  MusicServerCapability { MusicServerCapabilityNone = 0 , MusicServerCapabilityPlaybackStateReporting = (1 << 0) , MusicServerCapabilityProgressReporting = (1 << 1) , MusicServerCapabilityVolumeReporting = (1 << 2) }
 Optional features of a music backend, as a bitset. More...
 

Functions

void music_get_now_playing (char *title, char *artist, char *album)
 Copy the current track metadata.
 
bool music_has_now_playing (void)
 Check whether now-playing metadata is available.
 
bool music_get_player_name (char *player_name_out)
 Copy the name of the current player.
 
uint32_t music_get_ms_since_pos_last_updated (void)
 Time since the backend last reported the track position.
 
void music_get_pos (uint32_t *track_pos_ms, uint32_t *track_length_ms)
 Get the estimated track position and the track length.
 
int32_t music_get_playback_rate_percent (void)
 Get the playback rate.
 
uint8_t music_get_volume_percent (void)
 Get the player volume.
 
MusicPlayState music_get_playback_state (void)
 Get the playback state.
 
bool music_is_playback_state_reporting_supported (void)
 Check whether the backend reports the playback state.
 
bool music_is_progress_reporting_supported (void)
 Check whether the backend reports playback progress.
 
bool music_is_volume_reporting_supported (void)
 Check whether the backend reports the player volume.
 
void music_command_send (MusicCommand command)
 Send a command to the player, best effort.
 
bool music_is_command_supported (MusicCommand command)
 Check whether the connected backend supports a command.
 
bool music_skip_seeks_within_track (void)
 Check whether next/previous track commands seek within the track.
 
bool music_needs_user_to_start_playback_on_phone (void)
 Check whether playback must be started by the user on the phone.
 
void music_request_reduced_latency (bool reduced_latency)
 Enable or disable a reduced latency mode on the backend connection.
 
void music_request_low_latency_for_period (uint32_t period_seconds)
 Request the lowest connection latency for a limited time.
 
const char * music_get_connected_server_debug_name (void)
 Get the debug name of the connected backend, for tests.
 
uint8_t music_get_now_playing_generation (void)
 Get the now-playing generation token.
 
bool music_album_art_is_current (void)
 Check whether the held album art belongs to the current track.
 
const struct GBitmap * music_album_art_lock (void)
 Borrow the current album art for drawing.
 
void music_album_art_unlock (void)
 Release the album art borrowed with music_album_art_lock().
 
void music_init (void)
 Initialize the music service.
 
void music_handle_media_event (const PebbleMediaEvent *event)
 Mark a media event as taken by KernelMain.
 
bool music_set_connected_server (const MusicServerImplementation *implementation, bool connected)
 Report that a backend connected or disconnected.
 
void music_update_now_playing (const char *title, size_t title_length, const char *artist, size_t artist_length, const char *album, size_t album_length)
 Update the current track metadata.
 
void music_update_player_name (const char *player_name, size_t player_name_length)
 Update the name of the current player.
 
void music_update_player_playback_state (const MusicPlayerStateUpdate *state)
 Update playback state, rate and track position at once.
 
void music_update_player_volume_percent (uint8_t volume_percent)
 Update the volume of the current player.
 
void music_update_track_title (const char *title, size_t title_length)
 Update the title of the current track.
 
void music_update_track_artist (const char *artist, size_t artist_length)
 Update the artist of the current track.
 
void music_update_track_album (const char *album, size_t album_length)
 Update the album of the current track.
 
void music_update_track_position (uint32_t track_pos_ms)
 Update the position in the current track.
 
void music_update_track_duration (uint32_t track_duration_ms)
 Update the duration of the current track.
 
void music_set_album_art (struct GBitmap *bitmap, uint8_t token)
 Hand the album art of the current track to the service.
 
void music_album_art_transfer_failed (uint8_t token)
 Report that an album art transfer ended without an image.
 

Detailed Description

Now-playing metadata cache and media control.

Abstracts the music backend (the Pebble Protocol music endpoint or the Apple Media Service) behind a single interface used by the Music app. Only one backend is connected at a time. The service caches the last reported metadata and player state, and emits PEBBLE_MEDIA_EVENT events when they change. All functions are thread safe.

music_get_now_playing(title, artist, album);
}
}
void music_get_now_playing(char *title, char *artist, char *album)
Copy the current track metadata.
void music_command_send(MusicCommand command)
Send a command to the player, best effort.
bool music_is_command_supported(MusicCommand command)
Check whether the connected backend supports a command.
bool music_has_now_playing(void)
Check whether now-playing metadata is available.
#define MUSIC_BUFFER_LENGTH
Size of the string buffers used for metadata, including the terminator.
Definition music.h:34
@ MusicCommandTogglePlayPause
Toggle between play and pause.
Definition music.h:59

Data Structure Documentation

◆ MusicPlayerStateUpdate

struct MusicPlayerStateUpdate

Playback state update.

See also
music_update_player_playback_state
Data Fields
uint32_t elapsed_time_ms Track position in milliseconds.
int32_t playback_rate_percent Playback rate in percent, 100 being normal speed.
MusicPlayState playback_state Playback state.
bool skip_seeks_within_track See music_skip_seeks_within_track().

Macro Definition Documentation

◆ MUSIC_BUFFER_LENGTH

#define MUSIC_BUFFER_LENGTH   64

Size of the string buffers used for metadata, including the terminator.

Enumeration Type Documentation

◆ MusicCommand

Control command sent to the player.

Enumerator
MusicCommandPlay 

Start playback.

MusicCommandPause 

Pause playback.

MusicCommandTogglePlayPause 

Toggle between play and pause.

MusicCommandNextTrack 

Next track, or seek forward when music_skip_seeks_within_track() is true.

MusicCommandPreviousTrack 

Previous track, or seek backward when music_skip_seeks_within_track() is true.

MusicCommandVolumeUp 

Raise the volume.

MusicCommandVolumeDown 

Lower the volume.

MusicCommandAdvanceRepeatMode 

Cycle the repeat mode.

MusicCommandAdvanceShuffleMode 

Cycle the shuffle mode.

MusicCommandSkipForward 

Skip forward within the track.

MusicCommandSkipBackward 

Skip backward within the track.

MusicCommandLike 

Like the current track.

MusicCommandDislike 

Dislike the current track.

MusicCommandBookmark 

Bookmark the current track.

NumMusicCommand 

Number of commands.

◆ MusicPlayState

Playback state of the player.

Enumerator
MusicPlayStateUnknown 

State not known or not reported.

MusicPlayStatePlaying 

Playing.

MusicPlayStatePaused 

Paused.

MusicPlayStateForwarding 

Fast-forwarding.

MusicPlayStateRewinding 

Rewinding.

MusicPlayStateInvalid 

Backend reported an unrecognized state.

◆ MusicServerCapability

Optional features of a music backend, as a bitset.

Enumerator
MusicServerCapabilityNone 

No optional feature.

MusicServerCapabilityPlaybackStateReporting 

Reports the playback state.

MusicServerCapabilityProgressReporting 

Reports the track position.

MusicServerCapabilityVolumeReporting 

Reports the player volume.

Function Documentation

◆ music_album_art_is_current()

bool music_album_art_is_current ( void  )

Check whether the held album art belongs to the current track.

True once a response (art or "no art") was received for the current generation. The previous track's art is kept until then, so use this rather than the presence of art to decide whether to request art for the current track.

Returns
True if the album art is current.

◆ music_album_art_lock()

const struct GBitmap * music_album_art_lock ( void  )

Borrow the current album art for drawing.

Holds the service lock until music_album_art_unlock(), which must always be called, even when NULL is returned. The pointer must not be used after unlocking.

Returns
Album art owned by the service, or NULL if there is none.

◆ music_album_art_transfer_failed()

void music_album_art_transfer_failed ( uint8_t  token)

Report that an album art transfer ended without an image.

Parameters
tokenNow-playing generation the art was requested for.

◆ music_album_art_unlock()

void music_album_art_unlock ( void  )

Release the album art borrowed with music_album_art_lock().

◆ music_command_send()

void music_command_send ( MusicCommand  command)

Send a command to the player, best effort.

Does nothing when no backend is connected. Delivery is not confirmed.

Parameters
commandCommand to send.
See also
music_is_command_supported

◆ music_get_connected_server_debug_name()

const char * music_get_connected_server_debug_name ( void  )

Get the debug name of the connected backend, for tests.

Returns
Debug name, or NULL when no backend is connected.

◆ music_get_ms_since_pos_last_updated()

uint32_t music_get_ms_since_pos_last_updated ( void  )

Time since the backend last reported the track position.

Returns
Elapsed time in milliseconds.

◆ music_get_now_playing()

void music_get_now_playing ( char *  title,
char *  artist,
char *  album 
)

Copy the current track metadata.

Parameters
[out]titleTitle buffer of at least MUSIC_BUFFER_LENGTH bytes, or NULL.
[out]artistArtist buffer of at least MUSIC_BUFFER_LENGTH bytes, or NULL.
[out]albumAlbum buffer of at least MUSIC_BUFFER_LENGTH bytes, or NULL.

◆ music_get_now_playing_generation()

uint8_t music_get_now_playing_generation ( void  )

Get the now-playing generation token.

The 8-bit token changes whenever the title, artist or album changes. The Music app re-requests album art when it changes, and backends echo it in album art transfers so that art arriving after a track change can be discarded.

Returns
Current generation.
See also
music_set_album_art

◆ music_get_playback_rate_percent()

int32_t music_get_playback_rate_percent ( void  )

Get the playback rate.

Returns
Rate in percent: 100 is normal speed, 0 paused, negative values play backwards.

◆ music_get_playback_state()

MusicPlayState music_get_playback_state ( void  )

Get the playback state.

Returns
Current state, or MusicPlayStateUnknown if the backend does not report it.

◆ music_get_player_name()

bool music_get_player_name ( char *  player_name_out)

Copy the name of the current player.

Parameters
[out]player_name_outBuffer of at least MUSIC_BUFFER_LENGTH bytes, or NULL.
Returns
True if a player name is known.

◆ music_get_pos()

void music_get_pos ( uint32_t *  track_pos_ms,
uint32_t *  track_length_ms 
)

Get the estimated track position and the track length.

The position is extrapolated from the last reported one using the playback rate, and clamped to the track length.

Parameters
[out]track_pos_msPosition in milliseconds. Must not be NULL.
[out]track_length_msTrack length in milliseconds. Must not be NULL.

◆ music_get_volume_percent()

uint8_t music_get_volume_percent ( void  )

Get the player volume.

Returns
Volume in percent, 0 to 100.

◆ music_handle_media_event()

void music_handle_media_event ( const PebbleMediaEvent *  event)

Mark a media event as taken by KernelMain.

Now-playing and track position events are coalesced: a new one is only posted once the previous one has been taken. Consumers must read the current state through the music_get_*() functions. Must be called before the event is dispatched.

Parameters
eventMedia event taken from the KernelMain queue.

◆ music_has_now_playing()

bool music_has_now_playing ( void  )

Check whether now-playing metadata is available.

Returns
True if a title or an artist is known.

◆ music_init()

void music_init ( void  )

Initialize the music service.

◆ music_is_command_supported()

bool music_is_command_supported ( MusicCommand  command)

Check whether the connected backend supports a command.

Parameters
commandCommand to test.
Returns
True if supported, false if not or when no backend is connected.

◆ music_is_playback_state_reporting_supported()

bool music_is_playback_state_reporting_supported ( void  )

Check whether the backend reports the playback state.

Returns
True if supported.
See also
music_get_playback_state

◆ music_is_progress_reporting_supported()

bool music_is_progress_reporting_supported ( void  )

Check whether the backend reports playback progress.

Returns
True if supported and the current track has a non-zero length.
See also
music_get_pos

◆ music_is_volume_reporting_supported()

bool music_is_volume_reporting_supported ( void  )

Check whether the backend reports the player volume.

Returns
True if supported.
See also
music_get_volume_percent

◆ music_needs_user_to_start_playback_on_phone()

bool music_needs_user_to_start_playback_on_phone ( void  )

Check whether playback must be started by the user on the phone.

Returns
True if so, false otherwise or when no backend is connected.

◆ music_request_low_latency_for_period()

void music_request_low_latency_for_period ( uint32_t  period_seconds)

Request the lowest connection latency for a limited time.

Parameters
period_secondsDuration in milliseconds, despite the name.

◆ music_request_reduced_latency()

void music_request_reduced_latency ( bool  reduced_latency)

Enable or disable a reduced latency mode on the backend connection.

Parameters
reduced_latencyTrue to request reduced latency, false to release the request.

◆ music_set_album_art()

void music_set_album_art ( struct GBitmap *  bitmap,
uint8_t  token 
)

Hand the album art of the current track to the service.

Ownership of the bitmap, its pixel data and its palette, all allocated on the kernel heap, passes to the service, which frees the previous art. Art whose token does not match the current now-playing generation is stale and is freed immediately.

Parameters
bitmapAlbum art, or NULL to report that the track has none.
tokenNow-playing generation the art was requested for.

◆ music_set_connected_server()

bool music_set_connected_server ( const MusicServerImplementation *  implementation,
bool  connected 
)

Report that a backend connected or disconnected.

Only one backend can be connected at a time; a second one is rejected. Every connection change resets the cached metadata and state. Only one instance of each backend type exists, so the implementation pointer identifies it.

Parameters
implementationBackend operations.
connectedTrue on connection, false on disconnection.
Returns
True if the state changed. On false the backend must not call any music_update_*() function.

◆ music_skip_seeks_within_track()

bool music_skip_seeks_within_track ( void  )

Check whether next/previous track commands seek within the track.

True for podcasts and audiobooks. The commands to send are the same either way; this only tells the Music app which icons to show.

Returns
True if MusicCommandNextTrack and MusicCommandPreviousTrack seek within the track.

◆ music_update_now_playing()

void music_update_now_playing ( const char *  title,
size_t  title_length,
const char *  artist,
size_t  artist_length,
const char *  album,
size_t  album_length 
)

Update the current track metadata.

Strings need not be NUL terminated and are truncated to fit MUSIC_BUFFER_LENGTH. A change of any field bumps the now-playing generation.

Parameters
titleTrack title.
title_lengthLength of title in bytes.
artistTrack artist.
artist_lengthLength of artist in bytes.
albumTrack album.
album_lengthLength of album in bytes.

◆ music_update_player_name()

void music_update_player_name ( const char *  player_name,
size_t  player_name_length 
)

Update the name of the current player.

Parameters
player_namePlayer name, need not be NUL terminated.
player_name_lengthLength of player_name in bytes.

◆ music_update_player_playback_state()

void music_update_player_playback_state ( const MusicPlayerStateUpdate *  state)

Update playback state, rate and track position at once.

Parameters
stateNew state.

◆ music_update_player_volume_percent()

void music_update_player_volume_percent ( uint8_t  volume_percent)

Update the volume of the current player.

Parameters
volume_percentVolume, 0 to 100.

◆ music_update_track_album()

void music_update_track_album ( const char *  album,
size_t  album_length 
)

Update the album of the current track.

Does not bump the now-playing generation.

Parameters
albumAlbum, need not be NUL terminated.
album_lengthLength of album in bytes.

◆ music_update_track_artist()

void music_update_track_artist ( const char *  artist,
size_t  artist_length 
)

Update the artist of the current track.

Does not bump the now-playing generation.

Parameters
artistArtist, need not be NUL terminated.
artist_lengthLength of artist in bytes.

◆ music_update_track_duration()

void music_update_track_duration ( uint32_t  track_duration_ms)

Update the duration of the current track.

Parameters
track_duration_msDuration in milliseconds.

◆ music_update_track_position()

void music_update_track_position ( uint32_t  track_pos_ms)

Update the position in the current track.

Parameters
track_pos_msPosition in milliseconds.

◆ music_update_track_title()

void music_update_track_title ( const char *  title,
size_t  title_length 
)

Update the title of the current track.

Unlike music_update_now_playing(), this does not bump the now-playing generation.

Parameters
titleTitle, need not be NUL terminated.
title_lengthLength of title in bytes.