mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 02:38:35 -07:00
Update WAV Player, 16 bit support
by @LTVA1, in current condition has some issues with rewind on 16bit files, but plays them without problems
This commit is contained in:
111
applications/external/wav_player/wav_player.c
vendored
111
applications/external/wav_player/wav_player.c
vendored
@@ -127,7 +127,7 @@ static void app_free(WavPlayerApp* app) {
|
||||
|
||||
// TODO: that works only with 8-bit 2ch audio
|
||||
static bool fill_data(WavPlayerApp* app, size_t index) {
|
||||
if(app->num_channels == 1) {
|
||||
if(app->num_channels == 1 && app->bits_per_sample == 8) {
|
||||
uint16_t* sample_buffer_start = &app->sample_buffer[index];
|
||||
size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count_half);
|
||||
|
||||
@@ -166,7 +166,108 @@ static bool fill_data(WavPlayerApp* app, size_t index) {
|
||||
return count != app->samples_count_half;
|
||||
}
|
||||
|
||||
if(app->num_channels == 2) {
|
||||
if(app->num_channels == 1 && app->bits_per_sample == 16) {
|
||||
uint16_t* sample_buffer_start = &app->sample_buffer[index];
|
||||
size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
|
||||
|
||||
for(size_t i = count; i < app->samples_count; i++) {
|
||||
//app->tmp_buffer[i] = 0;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < app->samples_count; i += 2) {
|
||||
int16_t int_16 =
|
||||
(((int16_t)app->tmp_buffer[i + 1] << 8) + (int16_t)app->tmp_buffer[i]);
|
||||
|
||||
float data = ((float)int_16 / 256.0 + 127.0);
|
||||
data -= UINT8_MAX / 2; // to signed
|
||||
data /= UINT8_MAX / 2; // scale -1..1
|
||||
|
||||
data *= app->volume; // volume
|
||||
data = tanhf(data); // hyperbolic tangent limiter
|
||||
|
||||
data *= UINT8_MAX / 2; // scale -128..127
|
||||
data += UINT8_MAX / 2; // to unsigned
|
||||
|
||||
if(data < 0) {
|
||||
data = 0;
|
||||
}
|
||||
|
||||
if(data > 255) {
|
||||
data = 255;
|
||||
}
|
||||
|
||||
sample_buffer_start[i / 2] = data;
|
||||
}
|
||||
|
||||
wav_player_view_set_data(app->view, sample_buffer_start, app->samples_count_half);
|
||||
|
||||
return count != app->samples_count;
|
||||
}
|
||||
|
||||
if(app->num_channels == 2 && app->bits_per_sample == 16) {
|
||||
uint16_t* sample_buffer_start = &app->sample_buffer[index];
|
||||
size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
|
||||
|
||||
for(size_t i = 0; i < app->samples_count; i += 4) {
|
||||
int16_t L = (((int16_t)app->tmp_buffer[i + 1] << 8) + (int16_t)app->tmp_buffer[i]);
|
||||
int16_t R = (((int16_t)app->tmp_buffer[i + 3] << 8) + (int16_t)app->tmp_buffer[i + 2]);
|
||||
int32_t int_16 = L / 2 + R / 2; // (L + R) / 2
|
||||
|
||||
float data = ((float)int_16 / 256.0 + 127.0);
|
||||
data -= UINT8_MAX / 2; // to signed
|
||||
data /= UINT8_MAX / 2; // scale -1..1
|
||||
|
||||
data *= app->volume; // volume
|
||||
data = tanhf(data); // hyperbolic tangent limiter
|
||||
|
||||
data *= UINT8_MAX / 2; // scale -128..127
|
||||
data += UINT8_MAX / 2; // to unsigned
|
||||
|
||||
if(data < 0) {
|
||||
data = 0;
|
||||
}
|
||||
|
||||
if(data > 255) {
|
||||
data = 255;
|
||||
}
|
||||
|
||||
sample_buffer_start[i / 4] = data;
|
||||
}
|
||||
|
||||
count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
|
||||
|
||||
for(size_t i = 0; i < app->samples_count; i += 4) {
|
||||
int16_t L = (((int16_t)app->tmp_buffer[i + 1] << 8) + (int16_t)app->tmp_buffer[i]);
|
||||
int16_t R = (((int16_t)app->tmp_buffer[i + 3] << 8) + (int16_t)app->tmp_buffer[i + 2]);
|
||||
int32_t int_16 = L / 2 + R / 2; // (L + R) / 2
|
||||
|
||||
float data = ((float)int_16 / 256.0 + 127.0);
|
||||
data -= UINT8_MAX / 2; // to signed
|
||||
data /= UINT8_MAX / 2; // scale -1..1
|
||||
|
||||
data *= app->volume; // volume
|
||||
data = tanhf(data); // hyperbolic tangent limiter
|
||||
|
||||
data *= UINT8_MAX / 2; // scale -128..127
|
||||
data += UINT8_MAX / 2; // to unsigned
|
||||
|
||||
if(data < 0) {
|
||||
data = 0;
|
||||
}
|
||||
|
||||
if(data > 255) {
|
||||
data = 255;
|
||||
}
|
||||
|
||||
sample_buffer_start[i / 4 + app->samples_count / 4] = data;
|
||||
}
|
||||
|
||||
wav_player_view_set_data(app->view, sample_buffer_start, app->samples_count_half);
|
||||
|
||||
return count != app->samples_count;
|
||||
}
|
||||
|
||||
if(app->num_channels == 2 && app->bits_per_sample == 8) {
|
||||
uint16_t* sample_buffer_start = &app->sample_buffer[index];
|
||||
size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
|
||||
|
||||
@@ -270,6 +371,9 @@ static void app_run(WavPlayerApp* app) {
|
||||
while(1) {
|
||||
if(furi_message_queue_get(app->queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||
if(event.type == WavPlayerEventHalfTransfer) {
|
||||
wav_player_view_set_chans(app->view, app->num_channels);
|
||||
wav_player_view_set_bits(app->view, app->bits_per_sample);
|
||||
|
||||
eof = fill_data(app, 0);
|
||||
wav_player_view_set_current(app->view, stream_tell(app->stream));
|
||||
if(eof) {
|
||||
@@ -280,6 +384,9 @@ static void app_run(WavPlayerApp* app) {
|
||||
}
|
||||
|
||||
} else if(event.type == WavPlayerEventFullTransfer) {
|
||||
wav_player_view_set_chans(app->view, app->num_channels);
|
||||
wav_player_view_set_bits(app->view, app->bits_per_sample);
|
||||
|
||||
eof = fill_data(app, app->samples_count_half);
|
||||
wav_player_view_set_current(app->view, stream_tell(app->stream));
|
||||
if(eof) {
|
||||
|
||||
Reference in New Issue
Block a user