|
29 | 29 | *---------------------------------------------------------------------------- |
30 | 30 | */ |
31 | 31 |
|
| 32 | +#include <stdint.h> // For uint64_t |
| 33 | +#include <limits.h> // For USHRT_MAX |
| 34 | + |
32 | 35 | #define LOG_TAG "Sonivox" |
33 | 36 | #include "log/log.h" |
34 | 37 |
|
|
47 | 50 | #include "jet_data.h" |
48 | 51 | #endif |
49 | 52 |
|
50 | | -#include "compute_tick_conv.c" |
51 | | - |
52 | 53 | //3 dls: The timebase for this module is adequate to keep MIDI and |
53 | 54 | //3 digital audio synchronized for only a few minutes. It should be |
54 | 55 | //3 sufficient for most mobile applications. If better accuracy is |
@@ -882,22 +883,23 @@ static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData |
882 | 883 | return result; |
883 | 884 | temp = (temp << 8) | c; |
884 | 885 | } |
885 | | - /* Replaced this horrible obfuscated code: |
| 886 | + // note: temp is microseconds per quarter note. if SMF tempo is 120 quarters per minute, then: |
| 887 | + // temp = 60'000'000 / 120 = 500'000 (SMF_DEFAULT_TIMEBASE) |
| 888 | + // temp will be maximum 28 bits. See also SMF_ParseHeader() and SMF_UpdateTime() |
886 | 889 | { |
887 | | - // pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000); |
888 | | - uint64_t temp64; |
889 | | - if (__builtin_mul_overflow(temp, 1024u, &temp64) || |
890 | | - pSMFData->ppqn == 0 || |
891 | | - (temp64 /= pSMFData->ppqn, false) || |
892 | | - __builtin_add_overflow(temp64, 500, &temp64) || |
893 | | - (temp64 /= 1000, false) || |
894 | | - temp64 > 65535) { |
895 | | - pSMFData->tickConv = 65535; |
| 890 | + uint64_t temp64 = temp * 1024; // will never overflow |
| 891 | + if (pSMFData->ppqn > 0) { |
| 892 | + // see https://en.wikipedia.org/wiki/MIDI_beat_clock#Pulses_per_quarter_note |
| 893 | + temp64 /= pSMFData->ppqn; // ticks per quarter note, values typically between 24 and 960 |
| 894 | + temp64 += 500; |
| 895 | + temp64 /= 1000; |
| 896 | + } |
| 897 | + if (temp64 > USHRT_MAX) { |
| 898 | + pSMFData->tickConv = 65535; // unlikely! |
896 | 899 | } else { |
897 | 900 | pSMFData->tickConv = (EAS_U16) temp64; |
898 | 901 | } |
899 | | - }*/ |
900 | | - pSMFData->tickConv = compute_tick_conv(temp, pSMFData->ppqn); |
| 902 | + } |
901 | 903 | pSMFData->flags |= SMF_FLAGS_HAS_TEMPO; |
902 | 904 | } |
903 | 905 |
|
|
0 commit comments