ref: 1de494ed50a7b368dafbcdf1b77f3c1e87332f85
parent: 7d5a28fd902385d1517de4ae47f73a8150dd02e3
author: Iliyas Jorio <iliyas@jor.io>
date: Thu Jul 30 17:58:13 EDT 2020
Implement mod playback speed multiplier
--- a/src/music.cpp
+++ b/src/music.cpp
@@ -38,7 +38,7 @@
{
if (s_musicChannel && !s_musicFast)
{
- printf("Implement Me! FastMusic (1.3x playback speed)\n");
+ s_musicChannel->SetPlaybackSpeed(1.3);
s_musicFast = true;
}
}
@@ -47,7 +47,7 @@
{
if (s_musicChannel && s_musicFast)
{
- printf("Implement Me! SlowMusic\n");
+ s_musicChannel->SetPlaybackSpeed(1.0);
s_musicFast = false;
}
}
--- a/src/support/ModStream.cpp
+++ b/src/support/ModStream.cpp
@@ -10,6 +10,7 @@
, replayBuffer(2048*8)
, rbOffset(0)
, rbLength(0)
+ , playbackSpeedMult(1.0)
{
ibxm::data d;
d.buffer = moduleFile.data();
@@ -26,6 +27,11 @@
printf("Rewind not supported\n");
}
+void ModStream::SetPlaybackSpeed(double f)
+{
+ playbackSpeedMult = f;
+}
+
void ModStream::FillBuffer(int16_t *output, int length)
{
length /= 2;
@@ -34,7 +40,7 @@
// refill replay buffer if exhausted
if (rbLength == 0) {
rbOffset = 0;
- rbLength = ibxm::replay_get_audio(replay, replayBuffer.data(), 0);
+ rbLength = ibxm::replay_get_audio(replay, replayBuffer.data(), 0, (int)(playbackSpeedMult * 100.0));
}
// number of stereo samples to copy from replay buffer to output buffer
--- a/src/support/ModStream.h
+++ b/src/support/ModStream.h
@@ -16,6 +16,7 @@
std::vector<int> replayBuffer;
int rbOffset;
int rbLength;
+ double playbackSpeedMult;
void Rewind2();
void FillBuffer(int16_t* buffer, int length);
@@ -22,5 +23,6 @@
public:
ModStream(std::vector<char>&& rawModule);
+ void SetPlaybackSpeed(double f);
};
}
\ No newline at end of file
--- a/src/support/ibxm.c
+++ b/src/support/ibxm.c
@@ -1854,21 +1854,21 @@
return replay;
}
-static int calculate_tick_len( int tempo, int sample_rate ) {
- return ( sample_rate * 5 ) / ( tempo * 2 );
+static int calculate_tick_len( int tempo, int sample_rate, int speed_percent ) {
+ return 100 * ( sample_rate * 5 ) / ( tempo * 2 ) / speed_percent;
}
/* Returns the length of the output buffer required by replay_get_audio(). */
-int calculate_mix_buf_len( int sample_rate ) {
- return ( calculate_tick_len( 32, sample_rate ) + 65 ) * 4;
+int calculate_mix_buf_len( int sample_rate, int speed_percent ) {
+ return ( calculate_tick_len( 32, sample_rate, speed_percent ) + 65 ) * 4;
}
/* Returns the song duration in samples at the current sampling rate. */
-int replay_calculate_duration( struct replay *replay ) {
+int replay_calculate_duration( struct replay *replay, int speed_multiplier_percent ) {
int count = 0, duration = 0;
replay_set_sequence_pos( replay, 0 );
while( count < 1 ) {
- duration += calculate_tick_len( replay->tempo, replay->sample_rate );
+ duration += calculate_tick_len( replay->tempo, replay->sample_rate, speed_multiplier_percent );
count = replay_tick( replay );
}
replay_set_sequence_pos( replay, 0 );
@@ -1877,6 +1877,7 @@
/* Seek to approximately the specified sample position.
The actual sample position reached is returned. */
+/*
int replay_seek( struct replay *replay, int sample_pos ) {
int idx, tick_len, current_pos = 0;
replay_set_sequence_pos( replay, 0 );
@@ -1892,6 +1893,7 @@
}
return current_pos;
}
+ */
static void replay_volume_ramp( struct replay *replay, int *mix_buf, int tick_len ) {
int idx, a1, a2, ramp_rate = 256 * 2048 / replay->sample_rate;
@@ -1914,9 +1916,9 @@
/* Generates audio and returns the number of stereo samples written into mix_buf.
Individual channels may be excluded using the mute bitmask. */
-int replay_get_audio( struct replay *replay, int *mix_buf, int mute ) {
+int replay_get_audio( struct replay *replay, int *mix_buf, int mute, int speed_multiplier ) {
struct channel *channel;
- int idx, num_channels, tick_len = calculate_tick_len( replay->tempo, replay->sample_rate );
+ int idx, num_channels, tick_len = calculate_tick_len( replay->tempo, replay->sample_rate, speed_multiplier );
/* Clear output buffer. */
memset( mix_buf, 0, ( tick_len + 65 ) * 4 * sizeof( int ) );
/* Resample. */
--- a/src/support/ibxm.h
+++ b/src/support/ibxm.h
@@ -54,19 +54,19 @@
/* Deallocate the specified replay. */
void dispose_replay(struct replay *replay);
/* Returns the song duration in samples at the current sampling rate. */
-int replay_calculate_duration(struct replay *replay);
+int replay_calculate_duration(struct replay *replay, int speed_multiplier_percent);
/* Seek to approximately the specified sample position.
The actual sample position reached is returned. */
-int replay_seek(struct replay *replay, int sample_pos);
+//int replay_seek(struct replay *replay, int sample_pos);
/* Set the pattern in the sequence to play. The tempo is reset to the default. */
void replay_set_sequence_pos(struct replay *replay, int pos);
/* Generates audio and returns the number of stereo samples written into mix_buf.
Individual channels may be excluded using the mute bitmask. */
-int replay_get_audio(struct replay *replay, int *mix_buf, int mute);
+int replay_get_audio(struct replay *replay, int *mix_buf, int mute, int speed_multiplier_percent);
/* Returns the currently playing pattern in the sequence.*/
int replay_get_sequence_pos(struct replay *replay);
/* Returns the currently playing row in the pattern. */
int replay_get_row(struct replay *replay);
/* Returns the length of the output buffer required by replay_get_audio(). */
-int calculate_mix_buf_len(int sample_rate);
+int calculate_mix_buf_len(int sample_rate, int speed_multiplier_percent);