Add seeking via touchscreen

- WAV: works perfectly
- FLAC: works perfectly but just a tad bit slower than WAV.
- MP3: works perfectly but a tad bit slower than FLAC.
- MOD: works perfectly
- OGG: works perfectly however might crash if you use it right after seeking at an index.
- OPUS: works perfectly however WILL crash if you use it right after seeking at an index, but works fine if you wait a second before seeking again. (cannot constantly seek like the others)
This commit is contained in:
Joel16 2019-05-17 13:52:41 -04:00
parent 51736030c7
commit e7109de726
15 changed files with 140 additions and 10 deletions

View File

@ -27,6 +27,7 @@ SceUInt64 Audio_GetPosition(void);
SceUInt64 Audio_GetLength(void);
SceUInt64 Audio_GetPositionSeconds(void);
SceUInt64 Audio_GetLengthSeconds(void);
void Audio_Seek(SceUInt64 index);
void Audio_Term(void);
#endif

View File

@ -9,6 +9,7 @@ SceUInt8 FLAC_GetChannels(void);
void FLAC_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 FLAC_GetPosition(void);
SceUInt64 FLAC_GetLength(void);
SceUInt64 FLAC_Seek(SceUInt64 index);
void FLAC_Term(void);
#endif

View File

@ -9,6 +9,7 @@ SceUInt8 MP3_GetChannels(void);
void MP3_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 MP3_GetPosition(void);
SceUInt64 MP3_GetLength(void);
SceUInt64 MP3_Seek(SceUInt64 index);
void MP3_Term(void);
#endif

View File

@ -9,6 +9,7 @@ SceUInt8 OGG_GetChannels(void);
void OGG_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 OGG_GetPosition(void);
SceUInt64 OGG_GetLength(void);
SceUInt64 OGG_Seek(SceUInt64 index);
void OGG_Term(void);
#endif

View File

@ -9,6 +9,7 @@ SceUInt8 OPUS_GetChannels(void);
void OPUS_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 OPUS_GetPosition(void);
SceUInt64 OPUS_GetLength(void);
SceUInt64 OPUS_Seek(SceUInt64 index);
void OPUS_Term(void);
#endif

View File

@ -9,6 +9,7 @@ SceUInt8 WAV_GetChannels(void);
void WAV_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 WAV_GetPosition(void);
SceUInt64 WAV_GetLength(void);
SceUInt64 WAV_Seek(SceUInt64 index);
void WAV_Term(void);
#endif

View File

@ -9,6 +9,7 @@ SceUInt8 XM_GetChannels(void);
void XM_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 XM_GetPosition(void);
SceUInt64 XM_GetLength(void);
SceUInt64 XM_Seek(SceUInt64 index);
void XM_Term(void);
#endif

View File

@ -279,6 +279,37 @@ SceUInt64 Audio_GetLengthSeconds(void) {
return (Audio_GetLength() / Audio_GetSampleRate());
}
void Audio_Seek(SceUInt64 index) {
switch(file_type) {
case FILE_TYPE_FLAC:
FLAC_Seek(index);
break;
case FILE_TYPE_MP3:
MP3_Seek(index);
break;
case FILE_TYPE_OGG:
OGG_Seek(index);
break;
case FILE_TYPE_OPUS:
OPUS_Seek(index);
break;
case FILE_TYPE_WAV:
WAV_Seek(index);
break;
case FILE_TYPE_XM:
XM_Seek(index);
break;
default:
break;
}
}
void Audio_Term(void) {
switch(file_type) {
case FILE_TYPE_FLAC:

View File

@ -109,7 +109,7 @@ SceUInt8 FLAC_GetChannels(void) {
void FLAC_Decode(void *buf, unsigned int length, void *userdata) {
frames_read += drflac_read_pcm_frames_s16(flac, (drflac_uint64)length, (drflac_int16 *)buf);
if (frames_read == flac->totalPCMFrameCount)
if (frames_read >= flac->totalPCMFrameCount)
playing = SCE_FALSE;
}
@ -121,6 +121,17 @@ SceUInt64 FLAC_GetLength(void) {
return flac->totalPCMFrameCount;
}
SceUInt64 FLAC_Seek(SceUInt64 index) {
drflac_uint64 seek_frame = (flac->totalPCMFrameCount * (index / 450.0));
if (drflac_seek_to_pcm_frame(flac, seek_frame) == DRFLAC_TRUE) {
frames_read = seek_frame;
return frames_read;
}
return -1;
}
void FLAC_Term(void) {
frames_read = 0;

View File

@ -123,6 +123,15 @@ int MP3_Init(const char *path) {
if (error != MPG123_OK)
return error;
error = mpg123_param(mp3, MPG123_FLAGS, MPG123_FORCE_SEEKABLE | MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
if (error != MPG123_OK)
return error;
// Let the seek index auto-grow and contain an entry for every frame
error = mpg123_param(mp3, MPG123_INDEX_SIZE, -1, 0.0);
if (error != MPG123_OK)
return error;
error = mpg123_param(mp3, MPG123_ADD_FLAGS, MPG123_PICTURE, 0.0);
if (error != MPG123_OK)
return error;
@ -163,15 +172,16 @@ int MP3_Init(const char *path) {
}
}
total_samples = mpg123_length(mp3);
mpg123_getformat(mp3, &sample_rate, &channels, NULL);
mpg123_format_none(mp3);
mpg123_format(mp3, sample_rate, channels, MPG123_ENC_SIGNED_16);
mpg123_format(mp3, 44100, channels, MPG123_ENC_SIGNED_16);
total_samples = mpg123_length(mp3);
return 0;
}
SceUInt32 MP3_GetSampleRate(void) {
return sample_rate;
return 44100;
}
SceUInt8 MP3_GetChannels(void) {
@ -183,7 +193,7 @@ void MP3_Decode(void *buf, unsigned int length, void *userdata) {
mpg123_read(mp3, buf, length * (sizeof(SceInt16) * 2), &done);
frames_read += done/(sizeof(SceInt16) * 2);
if (frames_read == total_samples)
if (frames_read >= total_samples)
playing = SCE_FALSE;
}
@ -195,6 +205,17 @@ SceUInt64 MP3_GetLength(void) {
return total_samples;
}
SceUInt64 MP3_Seek(SceUInt64 index) {
off_t seek_frame = (total_samples * (index / 450.0));
if (mpg123_seek(mp3, seek_frame, SEEK_SET) >= 0) {
frames_read = seek_frame;
return frames_read;
}
return -1;
}
void MP3_Term(void) {
frames_read = 0;

View File

@ -108,7 +108,7 @@ void OGG_Decode(void *buf, unsigned int length, void *userdata) {
OGG_FillBuffer((char *)buf);
samples_read = ov_pcm_tell(&ogg);
if (samples_read == max_lenth)
if (samples_read >= max_lenth)
playing = SCE_FALSE;
}
@ -120,6 +120,17 @@ SceUInt64 OGG_GetLength(void) {
return max_lenth;
}
SceUInt64 OGG_Seek(SceUInt64 index) {
ogg_int64_t seek_sample = (max_lenth * (index / 450.0));
if (ov_pcm_seek(&ogg, seek_sample) >= 0) {
samples_read = seek_sample;
return samples_read;
}
return -1;
}
void OGG_Term(void) {
samples_read = 0;

View File

@ -86,7 +86,7 @@ void OPUS_Decode(void *buf, unsigned int length, void *userdata) {
if (read)
samples_read = op_pcm_tell(opus);
if (samples_read == max_samples)
if (samples_read >= max_samples)
playing = SCE_FALSE;
}
@ -98,6 +98,19 @@ SceUInt64 OPUS_GetLength(void) {
return max_samples;
}
SceUInt64 OPUS_Seek(SceUInt64 index) {
if (op_seekable(opus) >= 0) {
ogg_int64_t seek_sample = (max_samples * (index / 450.0));
if (op_pcm_seek(opus, seek_sample) >= 0) {
samples_read = seek_sample;
return samples_read;
}
}
return -1;
}
void OPUS_Term(void) {
samples_read = 0;

View File

@ -23,7 +23,7 @@ SceUInt8 WAV_GetChannels(void) {
void WAV_Decode(void *buf, unsigned int length, void *userdata) {
frames_read += drwav_read_pcm_frames_s16(&wav, (drwav_uint64)length, (drwav_int16 *)buf);
if (frames_read == wav.totalPCMFrameCount)
if (frames_read >= wav.totalPCMFrameCount)
playing = SCE_FALSE;
}
@ -35,6 +35,17 @@ SceUInt64 WAV_GetLength(void) {
return wav.totalPCMFrameCount;
}
SceUInt64 WAV_Seek(SceUInt64 index) {
drwav_uint64 seek_frame = (wav.totalPCMFrameCount * (index / 450.0));
if (drwav_seek_to_pcm_frame(&wav, seek_frame) == DRWAV_TRUE) {
frames_read = seek_frame;
return frames_read;
}
return -1;
}
void WAV_Term(void) {
frames_read = 0;
drwav_uninit(&wav);

View File

@ -10,7 +10,9 @@ static SceUInt64 samples_read = 0, total_samples = 0;
int XM_Init(const char *path) {
xmp = xmp_create_context();
if (xmp_load_module(xmp, (char *)path) < 0)
char *xmp_path = strdup(path);
if (xmp_load_module(xmp, xmp_path) < 0)
return -1;
xmp_start_player(xmp, 44100, 0);
@ -38,7 +40,7 @@ void XM_Decode(void *buf, unsigned int length, void *userdata) {
xmp_play_buffer(xmp, buf, (int)length * (sizeof(SceInt16) * 2), 0);
samples_read += length;
if (samples_read == total_samples)
if (samples_read >= total_samples)
playing = SCE_FALSE;
}
@ -50,6 +52,17 @@ SceUInt64 XM_GetLength(void) {
return total_samples;
}
SceUInt64 XM_Seek(SceUInt64 index) {
int seek_sample = (total_samples * (index / 450.0));
if (xmp_seek_time(xmp, seek_sample/44.1) >= 0) {
samples_read = seek_sample;
return samples_read;
}
return -1;
}
void XM_Term(void) {
samples_read = 0;
xmp_end_player(xmp);

View File

@ -217,6 +217,18 @@ void Menu_PlayAudio(char *path) {
if (pressed & SCE_CTRL_ENTER)
Audio_Pause();
if (Touch_CheckHeld() && Touch_GetX() >= 460 && Touch_GetX() <= 910 && Touch_GetY() >= 480 && Touch_GetY() <= 505) {
// Pause first if not paused.
if (!Audio_IsPaused())
Audio_Pause();
Audio_Seek(Touch_GetX() - 460);
// Unpause.
if (Audio_IsPaused())
Audio_Pause();
}
if (pressed & SCE_CTRL_TRIANGLE) {
if (state == MUSIC_STATE_SHUFFLE)
state = MUSIC_STATE_NONE;