Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/SDK/playback_control.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "foobar2000-sdk-pch.h" | |
| 2 #include "playback_control.h" | |
| 3 #include "titleformat.h" | |
| 4 | |
| 5 static double parseFraction(const char * fraction) { | |
| 6 unsigned v = 0, d = 1; | |
| 7 while(pfc::char_is_numeric( *fraction) ) { | |
| 8 d *= 10; | |
| 9 v *= 10; | |
| 10 v += (unsigned) ( *fraction - '0' ); | |
| 11 ++fraction; | |
| 12 } | |
| 13 PFC_ASSERT( *fraction == 0 ); | |
| 14 return (double)v / (double)d; | |
| 15 } | |
| 16 | |
| 17 static double parse_time(const char * time) { | |
| 18 unsigned vTotal = 0, vCur = 0; | |
| 19 for(;;) { | |
| 20 char c = *time++; | |
| 21 if (c == 0) return (double) (vTotal + vCur); | |
| 22 else if (pfc::char_is_numeric( c ) ) { | |
| 23 vCur = vCur * 10 + (unsigned)(c-'0'); | |
| 24 } else if (c == ':') { | |
| 25 if (vCur >= 60) {PFC_ASSERT(!"Invalid input"); return 0; } | |
| 26 vTotal += vCur; vCur = 0; vTotal *= 60; | |
| 27 } else if (c == '.') { | |
| 28 return (double) (vTotal + vCur) + parseFraction(time); | |
| 29 } else { | |
| 30 PFC_ASSERT(!"Invalid input"); return 0; | |
| 31 } | |
| 32 } | |
| 33 } | |
| 34 | |
| 35 double playback_control::playback_get_length() | |
| 36 { | |
| 37 double rv = 0; | |
| 38 metadb_handle_ptr ptr; | |
| 39 if (get_now_playing(ptr)) | |
| 40 { | |
| 41 rv = ptr->get_length(); | |
| 42 } | |
| 43 return rv; | |
| 44 } | |
| 45 | |
| 46 double playback_control::playback_get_length_ex() { | |
| 47 double rv = 0; | |
| 48 metadb_handle_ptr ptr; | |
| 49 if (get_now_playing(ptr)) | |
| 50 { | |
| 51 rv = ptr->get_length(); | |
| 52 if (rv <= 0) { | |
| 53 pfc::string8 temp; | |
| 54 titleformat_object::ptr script; | |
| 55 titleformat_compiler::get()->compile_force(script, "[%length_ex%]"); | |
| 56 this->playback_format_title(NULL, temp, script, NULL, display_level_titles); | |
| 57 if (temp.length() > 0) rv = parse_time(temp); | |
| 58 } | |
| 59 } | |
| 60 return rv; | |
| 61 } | |
| 62 | |
| 63 | |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 void playback_control::userPrev() { | |
| 69 userActionHook(); | |
| 70 if (this->is_playing() && this->playback_can_seek() && this->playback_get_position() > 5) { | |
| 71 this->playback_seek(0); | |
| 72 } else { | |
| 73 this->previous(); | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 void playback_control::userNext() { | |
| 78 userActionHook(); | |
| 79 this->start(track_command_next); | |
| 80 } | |
| 81 | |
| 82 void playback_control::userMute() { | |
| 83 userActionHook(); | |
| 84 this->volume_mute_toggle(); | |
| 85 } | |
| 86 | |
| 87 void playback_control::userStop() { | |
| 88 userActionHook(); | |
| 89 this->stop(); | |
| 90 } | |
| 91 | |
| 92 void playback_control::userPlay() { | |
| 93 userActionHook(); | |
| 94 this->play_or_pause(); | |
| 95 } | |
| 96 | |
| 97 void playback_control::userPause() { | |
| 98 userActionHook(); | |
| 99 nonUserPause(); | |
| 100 } | |
| 101 | |
| 102 void playback_control::nonUserPause() { | |
| 103 if (this->is_playing()) { | |
| 104 this->pause(true); | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 void playback_control::userStart() { | |
| 109 userActionHook(); | |
| 110 if (this->is_playing()) { | |
| 111 this->pause(false); | |
| 112 } else { | |
| 113 this->start(); | |
| 114 } | |
| 115 } | |
| 116 static const double seekDelta = 30; | |
| 117 void playback_control::userFastForward() { | |
| 118 userActionHook(); | |
| 119 if (!this->playback_can_seek()) { | |
| 120 this->userNext(); return; | |
| 121 } | |
| 122 this->playback_seek_delta(seekDelta); | |
| 123 } | |
| 124 | |
| 125 void playback_control::userRewind() { | |
| 126 userActionHook(); | |
| 127 if (!this->playback_can_seek()) { | |
| 128 this->userPrev(); return; | |
| 129 } | |
| 130 double p = this->playback_get_position(); | |
| 131 if (p < 0) return; | |
| 132 if (p < seekDelta) { | |
| 133 if (p < seekDelta / 3) { | |
| 134 this->userPrev(); | |
| 135 } else { | |
| 136 this->playback_seek(0); | |
| 137 } | |
| 138 } else { | |
| 139 this->playback_seek_delta(-30); | |
| 140 } | |
| 141 } |
