add Mix_GetMusicPosition() call to retrieve current music playing position
authorVitaly Novichkov
Mon, 23 Dec 2019 14:01:02 +0300
changeset 111770412138c859
parent 1116 9835d67a27f9
child 1118 d711a86866aa
add Mix_GetMusicPosition() call to retrieve current music playing position
include/SDL_mixer.h
src/codecs/music_cmd.c
src/codecs/music_flac.c
src/codecs/music_fluidsynth.c
src/codecs/music_mad.c
src/codecs/music_mikmod.c
src/codecs/music_modplug.c
src/codecs/music_mpg123.c
src/codecs/music_nativemidi.c
src/codecs/music_ogg.c
src/codecs/music_opus.c
src/codecs/music_timidity.c
src/codecs/music_wav.c
src/music.c
src/music.h
     1.1 --- a/include/SDL_mixer.h	Mon Dec 23 14:01:02 2019 +0300
     1.2 +++ b/include/SDL_mixer.h	Mon Dec 23 14:01:02 2019 +0300
     1.3 @@ -611,6 +611,12 @@
     1.4  */
     1.5  extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position);
     1.6  
     1.7 +/*
     1.8 +    Get the time current position of music stream
     1.9 +    returns -1.0 if this feature is not supported for some codec
    1.10 + */
    1.11 +extern DECLSPEC double SDLCALL Mix_GetMusicPosition(Mix_Music *music);
    1.12 +
    1.13  /* Check the status of a specific channel.
    1.14     If the specified channel is -1, check all channels.
    1.15  */
     2.1 --- a/src/codecs/music_cmd.c	Mon Dec 23 14:01:02 2019 +0300
     2.2 +++ b/src/codecs/music_cmd.c	Mon Dec 23 14:01:02 2019 +0300
     2.3 @@ -280,6 +280,7 @@
     2.4      MusicCMD_IsPlaying,
     2.5      NULL,   /* GetAudio */
     2.6      NULL,   /* Seek */
     2.7 +    NULL,   /* Tell */
     2.8      NULL,   /* Duration */
     2.9      MusicCMD_Pause,
    2.10      MusicCMD_Resume,
     3.1 --- a/src/codecs/music_flac.c	Mon Dec 23 14:01:02 2019 +0300
     3.2 +++ b/src/codecs/music_flac.c	Mon Dec 23 14:01:02 2019 +0300
     3.3 @@ -686,6 +686,12 @@
     3.4      return 0;
     3.5  }
     3.6  
     3.7 +static double FLAC_Tell(void *context)
     3.8 +{
     3.9 +    FLAC_Music *music = (FLAC_Music *)context;
    3.10 +    return (double)music->pcm_pos / music->sample_rate;
    3.11 +}
    3.12 +
    3.13  /* Return music duration in seconds */
    3.14  static double FLAC_Duration(void *context)
    3.15  {
    3.16 @@ -730,6 +736,7 @@
    3.17      NULL,   /* IsPlaying */
    3.18      FLAC_GetAudio,
    3.19      FLAC_Seek,
    3.20 +    FLAC_Tell,
    3.21      FLAC_Duration,
    3.22      NULL,   /* Pause */
    3.23      NULL,   /* Resume */
     4.1 --- a/src/codecs/music_fluidsynth.c	Mon Dec 23 14:01:02 2019 +0300
     4.2 +++ b/src/codecs/music_fluidsynth.c	Mon Dec 23 14:01:02 2019 +0300
     4.3 @@ -310,6 +310,7 @@
     4.4      FLUIDSYNTH_IsPlaying,
     4.5      FLUIDSYNTH_GetAudio,
     4.6      NULL,   /* Seek */
     4.7 +    NULL,   /* Tell */
     4.8      NULL,   /* Duration */
     4.9      NULL,   /* Pause */
    4.10      NULL,   /* Resume */
     5.1 --- a/src/codecs/music_mad.c	Mon Dec 23 14:01:02 2019 +0300
     5.2 +++ b/src/codecs/music_mad.c	Mon Dec 23 14:01:02 2019 +0300
     5.3 @@ -472,6 +472,7 @@
     5.4      NULL,   /* IsPlaying */
     5.5      MAD_GetAudio,
     5.6      MAD_Seek,
     5.7 +    NULL,   /* Tell */
     5.8      NULL,   /* Duration */
     5.9      NULL,   /* Pause */
    5.10      NULL,   /* Resume */
     6.1 --- a/src/codecs/music_mikmod.c	Mon Dec 23 14:01:02 2019 +0300
     6.2 +++ b/src/codecs/music_mikmod.c	Mon Dec 23 14:01:02 2019 +0300
     6.3 @@ -490,6 +490,7 @@
     6.4      MIKMOD_IsPlaying,
     6.5      MIKMOD_GetAudio,
     6.6      MIKMOD_Seek,
     6.7 +    NULL,   /* Tell */
     6.8      NULL,   /* Duration */
     6.9      NULL,   /* Pause */
    6.10      NULL,   /* Resume */
     7.1 --- a/src/codecs/music_modplug.c	Mon Dec 23 14:01:02 2019 +0300
     7.2 +++ b/src/codecs/music_modplug.c	Mon Dec 23 14:01:02 2019 +0300
     7.3 @@ -318,6 +318,7 @@
     7.4      NULL,   /* IsPlaying */
     7.5      MODPLUG_GetAudio,
     7.6      MODPLUG_Seek,
     7.7 +    NULL,   /* Tell */
     7.8      MODPLUG_Duration,
     7.9      NULL,   /* Pause */
    7.10      NULL,   /* Resume */
     8.1 --- a/src/codecs/music_mpg123.c	Mon Dec 23 14:01:02 2019 +0300
     8.2 +++ b/src/codecs/music_mpg123.c	Mon Dec 23 14:01:02 2019 +0300
     8.3 @@ -52,6 +52,7 @@
     8.4      int (*mpg123_read)(mpg123_handle *mh, unsigned char *outmemory, size_t outmemsize, size_t *done );
     8.5      int (*mpg123_replace_reader_handle)( mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), off_t (*r_lseek)(void *, off_t, int), void (*cleanup)(void*) );
     8.6      off_t (*mpg123_seek)( mpg123_handle *mh, off_t sampleoff, int whence );
     8.7 +    off_t (*mpg123_tell)( mpg123_handle *mh);
     8.8      off_t (*mpg123_length)(mpg123_handle *mh);
     8.9      const char* (*mpg123_strerror)(mpg123_handle *mh);
    8.10  } mpg123_loader;
    8.11 @@ -100,6 +101,7 @@
    8.12          FUNCTION_LOADER(mpg123_read, int (*)(mpg123_handle *mh, unsigned char *outmemory, size_t outmemsize, size_t *done ))
    8.13          FUNCTION_LOADER(mpg123_replace_reader_handle, int (*)( mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), off_t (*r_lseek)(void *, off_t, int), void (*cleanup)(void*) ))
    8.14          FUNCTION_LOADER(mpg123_seek, off_t (*)( mpg123_handle *mh, off_t sampleoff, int whence ))
    8.15 +        FUNCTION_LOADER(mpg123_tell, off_t (*)( mpg123_handle *mh))
    8.16          FUNCTION_LOADER(mpg123_length, off_t (*)(mpg123_handle *mh))
    8.17          FUNCTION_LOADER(mpg123_strerror, const char* (*)(mpg123_handle *mh))
    8.18      }
    8.19 @@ -429,6 +431,19 @@
    8.20      return 0;
    8.21  }
    8.22  
    8.23 +static double MPG123_Tell(void *context)
    8.24 +{
    8.25 +    MPG123_Music *music = (MPG123_Music *)context;
    8.26 +    off_t offset = 0;
    8.27 +    if (!music->sample_rate) {
    8.28 +        return 0.0;
    8.29 +    }
    8.30 +    if ((offset = mpg123.mpg123_tell(music->handle)) < 0) {
    8.31 +        return Mix_SetError("mpg123_tell: %s", mpg_err(music->handle, (int)-offset));
    8.32 +    }
    8.33 +    return (double)offset / music->sample_rate;
    8.34 +}
    8.35 +
    8.36  /* Return music duration in seconds */
    8.37  static double MPG123_Duration(void *context)
    8.38  {
    8.39 @@ -482,6 +497,7 @@
    8.40      NULL,   /* IsPlaying */
    8.41      MPG123_GetAudio,
    8.42      MPG123_Seek,
    8.43 +    MPG123_Tell,
    8.44      MPG123_Duration,
    8.45      NULL,   /* Pause */
    8.46      NULL,   /* Resume */
     9.1 --- a/src/codecs/music_nativemidi.c	Mon Dec 23 14:01:02 2019 +0300
     9.2 +++ b/src/codecs/music_nativemidi.c	Mon Dec 23 14:01:02 2019 +0300
     9.3 @@ -101,6 +101,7 @@
     9.4      NATIVEMIDI_IsPlaying,
     9.5      NULL,   /* GetAudio */
     9.6      NULL,   /* Seek */
     9.7 +    NULL,   /* Tell */
     9.8      NULL,   /* Duration */
     9.9      NATIVEMIDI_Pause,
    9.10      NATIVEMIDI_Resume,
    10.1 --- a/src/codecs/music_ogg.c	Mon Dec 23 14:01:02 2019 +0300
    10.2 +++ b/src/codecs/music_ogg.c	Mon Dec 23 14:01:02 2019 +0300
    10.3 @@ -48,10 +48,12 @@
    10.4  #ifdef OGG_USE_TREMOR
    10.5      long (*ov_read)(OggVorbis_File *vf,char *buffer,int length, int *bitstream);
    10.6      int (*ov_time_seek)(OggVorbis_File *vf,ogg_int64_t pos);
    10.7 +    ogg_int64_t (*ov_time_tell)(OggVorbis_File *vf);
    10.8      ogg_int64_t (*ov_time_total)(OggVorbis_File *vf, int i);
    10.9  #else
   10.10      long (*ov_read)(OggVorbis_File *vf,char *buffer,int length, int bigendianp,int word,int sgned,int *bitstream);
   10.11      int (*ov_time_seek)(OggVorbis_File *vf,double pos);
   10.12 +    double (*ov_time_tell)(OggVorbis_File *vf);
   10.13      double (*ov_time_total)(OggVorbis_File *vf, int i);
   10.14  #endif
   10.15      int (*ov_pcm_seek)(OggVorbis_File *vf, ogg_int64_t pos);
   10.16 @@ -96,10 +98,12 @@
   10.17  #ifdef OGG_USE_TREMOR
   10.18          FUNCTION_LOADER(ov_read, long (*)(OggVorbis_File *,char *,int,int *))
   10.19          FUNCTION_LOADER(ov_time_seek, int (*)(OggVorbis_File *,ogg_int64_t))
   10.20 +        FUNCTION_LOADER(ov_time_tell, ogg_int64_t (*)(OggVorbis_File *))
   10.21          FUNCTION_LOADER(ov_time_total, ogg_int64_t (*)(OggVorbis_File *, int))
   10.22  #else
   10.23          FUNCTION_LOADER(ov_read, long (*)(OggVorbis_File *,char *,int,int,int,int,int *))
   10.24          FUNCTION_LOADER(ov_time_seek, int (*)(OggVorbis_File *,double))
   10.25 +        FUNCTION_LOADER(ov_time_tell, double (*)(OggVorbis_File *))
   10.26          FUNCTION_LOADER(ov_time_total, double (*)(OggVorbis_File *, int))
   10.27  #endif
   10.28          FUNCTION_LOADER(ov_pcm_seek, int (*)(OggVorbis_File *,ogg_int64_t))
   10.29 @@ -468,6 +472,16 @@
   10.30      return 0;
   10.31  }
   10.32  
   10.33 +static double OGG_Tell(void *context)
   10.34 +{
   10.35 +    OGG_music *music = (OGG_music *)context;
   10.36 +#ifdef OGG_USE_TREMOR
   10.37 +    return vorbis.ov_time_tell(&music->vf) / 1000.0;
   10.38 +#else
   10.39 +    return vorbis.ov_time_tell(&music->vf);
   10.40 +#endif
   10.41 +}
   10.42 +
   10.43  /* Return music duration in seconds */
   10.44  static double OGG_Duration(void *context)
   10.45  {
   10.46 @@ -514,6 +528,7 @@
   10.47      NULL,   /* IsPlaying */
   10.48      OGG_GetAudio,
   10.49      OGG_Seek,
   10.50 +    OGG_Tell,
   10.51      OGG_Duration,
   10.52      NULL,   /* Pause */
   10.53      NULL,   /* Resume */
    11.1 --- a/src/codecs/music_opus.c	Mon Dec 23 14:01:02 2019 +0300
    11.2 +++ b/src/codecs/music_opus.c	Mon Dec 23 14:01:02 2019 +0300
    11.3 @@ -460,6 +460,12 @@
    11.4      return 0;
    11.5  }
    11.6  
    11.7 +static double OPUS_Tell(void *context)
    11.8 +{
    11.9 +    OPUS_music *music = (OPUS_music *)context;
   11.10 +    return (double)(opus.op_pcm_tell(music->of)) / 48000.0;
   11.11 +}
   11.12 +
   11.13  /* Return music duration in seconds */
   11.14  static double OPUS_Duration(void *context)
   11.15  {
   11.16 @@ -502,6 +508,7 @@
   11.17      NULL,   /* IsPlaying */
   11.18      OPUS_GetAudio,
   11.19      OPUS_Seek,
   11.20 +    OPUS_Tell,
   11.21      OPUS_Duration,
   11.22      NULL,   /* Pause */
   11.23      NULL,   /* Resume */
    12.1 --- a/src/codecs/music_timidity.c	Mon Dec 23 14:01:02 2019 +0300
    12.2 +++ b/src/codecs/music_timidity.c	Mon Dec 23 14:01:02 2019 +0300
    12.3 @@ -256,6 +256,7 @@
    12.4      NULL,   /* IsPlaying */
    12.5      TIMIDITY_GetAudio,
    12.6      TIMIDITY_Seek,
    12.7 +    NULL,   /* Tell */
    12.8      TIMIDITY_Duration,
    12.9      NULL,   /* Pause */
   12.10      NULL,   /* Resume */
    13.1 --- a/src/codecs/music_wav.c	Mon Dec 23 14:01:02 2019 +0300
    13.2 +++ b/src/codecs/music_wav.c	Mon Dec 23 14:01:02 2019 +0300
    13.3 @@ -585,6 +585,13 @@
    13.4      return 0;
    13.5  }
    13.6  
    13.7 +static double WAV_Tell(void *context)
    13.8 +{
    13.9 +    WAV_Music *music = (WAV_Music *)context;
   13.10 +    Sint64 phys_pos = SDL_RWtell(music->src);
   13.11 +    return (double)(phys_pos - music->start) / (double)(music->spec.freq * music->samplesize);
   13.12 +}
   13.13 +
   13.14  /* Return music duration in seconds */
   13.15  static double WAV_Duration(void *context)
   13.16  {
   13.17 @@ -1103,6 +1110,7 @@
   13.18      NULL,   /* IsPlaying */
   13.19      WAV_GetAudio,
   13.20      WAV_Seek,   /* Seek */
   13.21 +    WAV_Tell,   /* Tell */
   13.22      WAV_Duration,
   13.23      NULL,   /* Pause */
   13.24      NULL,   /* Resume */
    14.1 --- a/src/music.c	Mon Dec 23 14:01:02 2019 +0300
    14.2 +++ b/src/music.c	Mon Dec 23 14:01:02 2019 +0300
    14.3 @@ -795,6 +795,32 @@
    14.4      return(retval);
    14.5  }
    14.6  
    14.7 +/* Set the playing music position */
    14.8 +static double music_internal_position_get(Mix_Music *music)
    14.9 +{
   14.10 +    if (music->interface->Tell) {
   14.11 +        return music->interface->Tell(music->context);
   14.12 +    }
   14.13 +    return -1;
   14.14 +}
   14.15 +double Mix_GetMusicPosition(Mix_Music *music)
   14.16 +{
   14.17 +    double retval;
   14.18 +
   14.19 +    Mix_LockAudio();
   14.20 +    if (music) {
   14.21 +        retval = music_internal_position_get(music);
   14.22 +    } else if (music_playing) {
   14.23 +        retval = music_internal_position_get(music_playing);
   14.24 +    } else {
   14.25 +        Mix_SetError("Music isn't playing");
   14.26 +        retval = -1.0;
   14.27 +    }
   14.28 +    Mix_UnlockAudio();
   14.29 +
   14.30 +    return(retval);
   14.31 +}
   14.32 +
   14.33  static double music_internal_duration(Mix_Music *music)
   14.34  {
   14.35      if (music->interface->Duration) {
   14.36 @@ -809,14 +835,13 @@
   14.37      double retval;
   14.38  
   14.39      Mix_LockAudio();
   14.40 -
   14.41      if (music) {
   14.42          retval = music_internal_duration(music);
   14.43      } else if (music_playing) {
   14.44          retval = music_internal_duration(music_playing);
   14.45      } else {
   14.46          Mix_SetError("music is NULL and no playing music");
   14.47 -        retval = -1;
   14.48 +        retval = -1.0;
   14.49      }
   14.50      Mix_UnlockAudio();
   14.51  
    15.1 --- a/src/music.h	Mon Dec 23 14:01:02 2019 +0300
    15.2 +++ b/src/music.h	Mon Dec 23 14:01:02 2019 +0300
    15.3 @@ -85,6 +85,9 @@
    15.4      /* Seek to a play position (in seconds) */
    15.5      int (*Seek)(void *music, double position);
    15.6  
    15.7 +    /* Tell a play position (in seconds) */
    15.8 +    double (*Tell)(void *music);
    15.9 +
   15.10      /* Get Music duration (in seconds) */
   15.11      double (*Duration)(void *music);
   15.12