mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 23:09:26 -05:00
WAV Viewer & Soundboard enhancements (8 or 16-bit WAV files) (#1849)
* WAV Viewer & Soundboard enhancements * Reduced width of sample rate field
This commit is contained in:
parent
bc035cff6a
commit
5ea1bff1e6
@ -89,6 +89,7 @@ void SoundBoardView::start_tx(const uint32_t id) {
|
|||||||
|
|
||||||
uint32_t tone_key_index = options_tone_key.selected_index();
|
uint32_t tone_key_index = options_tone_key.selected_index();
|
||||||
uint32_t sample_rate;
|
uint32_t sample_rate;
|
||||||
|
uint8_t bits_per_sample;
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ void SoundBoardView::start_tx(const uint32_t id) {
|
|||||||
// button_play.set_bitmap(&bitmap_stop);
|
// button_play.set_bitmap(&bitmap_stop);
|
||||||
|
|
||||||
sample_rate = reader->sample_rate();
|
sample_rate = reader->sample_rate();
|
||||||
|
bits_per_sample = reader->bits_per_sample();
|
||||||
|
|
||||||
replay_thread = std::make_unique<ReplayThread>(
|
replay_thread = std::make_unique<ReplayThread>(
|
||||||
std::move(reader),
|
std::move(reader),
|
||||||
@ -120,7 +122,7 @@ void SoundBoardView::start_tx(const uint32_t id) {
|
|||||||
transmitter_model.channel_bandwidth(),
|
transmitter_model.channel_bandwidth(),
|
||||||
0, // Gain is unused
|
0, // Gain is unused
|
||||||
8, // shift_bits_s16, default 8 bits, but also unused
|
8, // shift_bits_s16, default 8 bits, but also unused
|
||||||
8, // bits per sample
|
bits_per_sample,
|
||||||
TONES_F2D(tone_key_frequency(tone_key_index), TONES_SAMPLERATE),
|
TONES_F2D(tone_key_frequency(tone_key_index), TONES_SAMPLERATE),
|
||||||
false, // AM
|
false, // AM
|
||||||
false, // DSB
|
false, // DSB
|
||||||
@ -172,7 +174,7 @@ void SoundBoardView::refresh_list() {
|
|||||||
|
|
||||||
if (entry_extension == ".WAV") {
|
if (entry_extension == ".WAV") {
|
||||||
if (reader->open(u"/WAV/" + entry.path().native())) {
|
if (reader->open(u"/WAV/" + entry.path().native())) {
|
||||||
if ((reader->channels() == 1) && (reader->bits_per_sample() == 8)) {
|
if ((reader->channels() == 1) && ((reader->bits_per_sample() == 8) || (reader->bits_per_sample() == 16))) {
|
||||||
// sounds[c].ms_duration = reader->ms_duration();
|
// sounds[c].ms_duration = reader->ms_duration();
|
||||||
// sounds[c].path = u"WAV/" + entry.path().native();
|
// sounds[c].path = u"WAV/" + entry.path().native();
|
||||||
if (count >= (page - 1) * 100 && count < page * 100) {
|
if (count >= (page - 1) * 100 && count < page * 100) {
|
||||||
|
@ -38,9 +38,17 @@ void ViewWavView::update_scale(int32_t new_scale) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ViewWavView::refresh_waveform() {
|
void ViewWavView::refresh_waveform() {
|
||||||
|
uint8_t bits_per_sample = wav_reader->bits_per_sample();
|
||||||
|
|
||||||
for (size_t i = 0; i < 240; i++) {
|
for (size_t i = 0; i < 240; i++) {
|
||||||
wav_reader->data_seek(position + (i * scale));
|
wav_reader->data_seek(position + (i * scale));
|
||||||
wav_reader->read(&waveform_buffer[i], sizeof(int16_t));
|
if (bits_per_sample == 8) {
|
||||||
|
uint8_t sample;
|
||||||
|
wav_reader->read(&sample, 1);
|
||||||
|
waveform_buffer[i] = (sample - 0x80) * 256;
|
||||||
|
} else {
|
||||||
|
wav_reader->read(&waveform_buffer[i], 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waveform.set_dirty();
|
waveform.set_dirty();
|
||||||
@ -73,13 +81,29 @@ void ViewWavView::paint(Painter& painter) {
|
|||||||
painter.draw_vline({(Coord)i, 11 * 16}, 8, spectrum_rgb2_lut[amplitude_buffer[i] << 1]);
|
painter.draw_vline({(Coord)i, 11 * 16}, 8, spectrum_rgb2_lut[amplitude_buffer[i] << 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewWavView::on_pos_changed() {
|
void ViewWavView::on_pos_time_changed() {
|
||||||
position = (field_pos_seconds.value() * wav_reader->sample_rate()) + field_pos_samples.value();
|
position = (uint64_t)((field_pos_seconds.value() * 1000) + field_pos_milliseconds.value()) * wav_reader->sample_rate() / 1000;
|
||||||
|
field_pos_milliseconds.set_range(0, ((uint32_t)field_pos_seconds.value() == wav_reader->ms_duration() / 1000) ? wav_reader->ms_duration() % 1000 : 999);
|
||||||
|
if (!updating_position) {
|
||||||
|
updating_position = true; // prevent recursion
|
||||||
|
field_pos_samples.set_value(position);
|
||||||
|
updating_position = false;
|
||||||
|
}
|
||||||
|
refresh_waveform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewWavView::on_pos_sample_changed() {
|
||||||
|
position = field_pos_samples.value();
|
||||||
|
if (!updating_position) {
|
||||||
|
updating_position = true; // prevent recursion
|
||||||
|
field_pos_seconds.set_value(field_pos_samples.value() / wav_reader->sample_rate());
|
||||||
|
field_pos_milliseconds.set_value((field_pos_samples.value() * 1000ull / wav_reader->sample_rate()) % 1000);
|
||||||
|
updating_position = false;
|
||||||
|
}
|
||||||
refresh_waveform();
|
refresh_waveform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewWavView::load_wav(std::filesystem::path file_path) {
|
void ViewWavView::load_wav(std::filesystem::path file_path) {
|
||||||
int16_t sample;
|
|
||||||
uint32_t average;
|
uint32_t average;
|
||||||
|
|
||||||
wav_file_path = file_path;
|
wav_file_path = file_path;
|
||||||
@ -91,19 +115,28 @@ void ViewWavView::load_wav(std::filesystem::path file_path) {
|
|||||||
wav_reader->rewind();
|
wav_reader->rewind();
|
||||||
|
|
||||||
text_samplerate.set(to_string_dec_uint(wav_reader->sample_rate()) + "Hz");
|
text_samplerate.set(to_string_dec_uint(wav_reader->sample_rate()) + "Hz");
|
||||||
|
text_bits_per_sample.set(to_string_dec_uint(wav_reader->bits_per_sample(), 2));
|
||||||
text_title.set(wav_reader->title());
|
text_title.set(wav_reader->title());
|
||||||
|
|
||||||
// Fill amplitude buffer, world's worst downsampling
|
// Fill amplitude buffer, world's worst downsampling
|
||||||
uint64_t skip = wav_reader->sample_count() / (240 * subsampling_factor);
|
uint64_t skip = wav_reader->sample_count() / (240 * subsampling_factor);
|
||||||
|
uint8_t bits_per_sample = wav_reader->bits_per_sample();
|
||||||
|
|
||||||
for (size_t i = 0; i < 240; i++) {
|
for (size_t i = 0; i < 240; i++) {
|
||||||
average = 0;
|
average = 0;
|
||||||
|
|
||||||
for (size_t s = 0; s < subsampling_factor; s++) {
|
for (size_t s = 0; s < subsampling_factor; s++) {
|
||||||
wav_reader->data_seek(((i * subsampling_factor) + s) * skip);
|
wav_reader->data_seek(((i * subsampling_factor) + s) * skip);
|
||||||
|
if (bits_per_sample == 8) {
|
||||||
|
uint8_t sample;
|
||||||
|
wav_reader->read(&sample, 1);
|
||||||
|
average += sample / 2;
|
||||||
|
} else {
|
||||||
|
int16_t sample;
|
||||||
wav_reader->read(&sample, 2);
|
wav_reader->read(&sample, 2);
|
||||||
average += (abs(sample) >> 8);
|
average += (abs(sample) >> 8);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
amplitude_buffer[i] = average / subsampling_factor;
|
amplitude_buffer[i] = average / subsampling_factor;
|
||||||
}
|
}
|
||||||
@ -154,6 +187,7 @@ void ViewWavView::file_error() {
|
|||||||
|
|
||||||
void ViewWavView::start_playback() {
|
void ViewWavView::start_playback() {
|
||||||
uint32_t sample_rate;
|
uint32_t sample_rate;
|
||||||
|
uint8_t bits_per_sample;
|
||||||
|
|
||||||
auto reader = std::make_unique<WAVFileReader>();
|
auto reader = std::make_unique<WAVFileReader>();
|
||||||
|
|
||||||
@ -167,6 +201,7 @@ void ViewWavView::start_playback() {
|
|||||||
button_play.set_bitmap(&bitmap_stop);
|
button_play.set_bitmap(&bitmap_stop);
|
||||||
|
|
||||||
sample_rate = reader->sample_rate();
|
sample_rate = reader->sample_rate();
|
||||||
|
bits_per_sample = reader->bits_per_sample();
|
||||||
|
|
||||||
progressbar.set_max(reader->sample_count());
|
progressbar.set_max(reader->sample_count());
|
||||||
|
|
||||||
@ -184,7 +219,7 @@ void ViewWavView::start_playback() {
|
|||||||
0, // Transmit BW = 0 = not transmitting
|
0, // Transmit BW = 0 = not transmitting
|
||||||
0, // Gain - unused
|
0, // Gain - unused
|
||||||
8, // shift_bits_s16, default 8 bits - unused
|
8, // shift_bits_s16, default 8 bits - unused
|
||||||
16, // bits per sample
|
bits_per_sample, // bits_per_sample
|
||||||
0, // tone key disabled
|
0, // tone key disabled
|
||||||
false, // AM
|
false, // AM
|
||||||
false, // DSB
|
false, // DSB
|
||||||
@ -192,6 +227,7 @@ void ViewWavView::start_playback() {
|
|||||||
false // LSB
|
false // LSB
|
||||||
);
|
);
|
||||||
baseband::set_sample_rate(sample_rate);
|
baseband::set_sample_rate(sample_rate);
|
||||||
|
transmitter_model.set_sampling_rate(1536000);
|
||||||
|
|
||||||
audio::output::start();
|
audio::output::start();
|
||||||
}
|
}
|
||||||
@ -211,11 +247,13 @@ ViewWavView::ViewWavView(
|
|||||||
&text_samplerate,
|
&text_samplerate,
|
||||||
&text_title,
|
&text_title,
|
||||||
&text_duration,
|
&text_duration,
|
||||||
|
&text_bits_per_sample,
|
||||||
&button_open,
|
&button_open,
|
||||||
&button_play,
|
&button_play,
|
||||||
&waveform,
|
&waveform,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
&field_pos_seconds,
|
&field_pos_seconds,
|
||||||
|
&field_pos_milliseconds,
|
||||||
&field_pos_samples,
|
&field_pos_samples,
|
||||||
&field_scale,
|
&field_scale,
|
||||||
&field_cursor_a,
|
&field_cursor_a,
|
||||||
@ -234,12 +272,16 @@ ViewWavView::ViewWavView(
|
|||||||
file_error();
|
file_error();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((wav_reader->channels() != 1) || (wav_reader->bits_per_sample() != 16)) {
|
if ((wav_reader->channels() != 1) || ((wav_reader->bits_per_sample() != 8) && (wav_reader->bits_per_sample() != 16))) {
|
||||||
nav_.display_modal("Error", "Wrong format.\nWav viewer only accepts\n16-bit mono files.");
|
nav_.display_modal("Error", "Wrong format.\nWav viewer only accepts\n8 or 16-bit mono files.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
load_wav(file_path);
|
load_wav(file_path);
|
||||||
field_pos_seconds.focus();
|
field_pos_seconds.focus();
|
||||||
|
field_pos_seconds.set_range(0, wav_reader->ms_duration() / 1000);
|
||||||
|
field_pos_milliseconds.set_range(0, (wav_reader->ms_duration() < 1000) ? wav_reader->ms_duration() % 1000 : 999);
|
||||||
|
field_pos_samples.set_range(0, wav_reader->sample_count() - 1);
|
||||||
|
field_scale.set_range(1, wav_reader->sample_count() / 240);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -257,10 +299,13 @@ ViewWavView::ViewWavView(
|
|||||||
update_scale(value);
|
update_scale(value);
|
||||||
};
|
};
|
||||||
field_pos_seconds.on_change = [this](int32_t) {
|
field_pos_seconds.on_change = [this](int32_t) {
|
||||||
on_pos_changed();
|
on_pos_time_changed();
|
||||||
|
};
|
||||||
|
field_pos_milliseconds.on_change = [this](int32_t) {
|
||||||
|
on_pos_time_changed();
|
||||||
};
|
};
|
||||||
field_pos_samples.on_change = [this](int32_t) {
|
field_pos_samples.on_change = [this](int32_t) {
|
||||||
on_pos_changed();
|
on_pos_sample_changed();
|
||||||
};
|
};
|
||||||
|
|
||||||
field_cursor_a.on_change = [this](int32_t v) {
|
field_cursor_a.on_change = [this](int32_t v) {
|
||||||
|
@ -49,7 +49,8 @@ class ViewWavView : public View {
|
|||||||
void update_scale(int32_t new_scale);
|
void update_scale(int32_t new_scale);
|
||||||
void refresh_waveform();
|
void refresh_waveform();
|
||||||
void refresh_measurements();
|
void refresh_measurements();
|
||||||
void on_pos_changed();
|
void on_pos_time_changed();
|
||||||
|
void on_pos_sample_changed();
|
||||||
void load_wav(std::filesystem::path file_path);
|
void load_wav(std::filesystem::path file_path);
|
||||||
void reset_controls();
|
void reset_controls();
|
||||||
bool is_active();
|
bool is_active();
|
||||||
@ -74,30 +75,35 @@ class ViewWavView : public View {
|
|||||||
int32_t scale{1};
|
int32_t scale{1};
|
||||||
uint64_t ns_per_pixel{};
|
uint64_t ns_per_pixel{};
|
||||||
uint64_t position{};
|
uint64_t position{};
|
||||||
|
bool updating_position{false};
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{0 * 8, 0 * 16}, "File:", Color::light_grey()},
|
{{0 * 8, 0 * 16}, "File:", Color::light_grey()},
|
||||||
{{0 * 8, 1 * 16}, "Samplerate:", Color::light_grey()},
|
{{2 * 8, 1 * 16}, "-bit mono", Color::light_grey()},
|
||||||
{{0 * 8, 2 * 16}, "Title:", Color::light_grey()},
|
{{0 * 8, 2 * 16}, "Title:", Color::light_grey()},
|
||||||
{{0 * 8, 3 * 16}, "Duration:", Color::light_grey()},
|
{{0 * 8, 3 * 16}, "Duration:", Color::light_grey()},
|
||||||
{{0 * 8, 12 * 16}, "Position: s Scale:", Color::light_grey()},
|
{{0 * 8, 12 * 16}, "Position: . s Scale:", Color::light_grey()},
|
||||||
{{0 * 8, 13 * 16}, "Cursor A:", Color::dark_cyan()},
|
{{0 * 8, 13 * 16}, " Sample:", Color::light_grey()},
|
||||||
{{0 * 8, 14 * 16}, "Cursor B:", Color::dark_magenta()},
|
{{0 * 8, 14 * 16}, "Cursor A:", Color::dark_cyan()},
|
||||||
{{0 * 8, 15 * 16}, "Delta:", Color::light_grey()},
|
{{0 * 8, 15 * 16}, "Cursor B:", Color::dark_magenta()},
|
||||||
|
{{0 * 8, 16 * 16}, "Delta:", Color::light_grey()},
|
||||||
{{24 * 8, 18 * 16}, "Vol:", Color::light_grey()}};
|
{{24 * 8, 18 * 16}, "Vol:", Color::light_grey()}};
|
||||||
|
|
||||||
Text text_filename{
|
Text text_filename{
|
||||||
{5 * 8, 0 * 16, 12 * 8, 16},
|
{5 * 8, 0 * 16, 18 * 8, 16},
|
||||||
""};
|
""};
|
||||||
Text text_samplerate{
|
Text text_samplerate{
|
||||||
{11 * 8, 1 * 16, 8 * 8, 16},
|
{12 * 8, 1 * 16, 10 * 8, 16},
|
||||||
""};
|
""};
|
||||||
Text text_title{
|
Text text_title{
|
||||||
{6 * 8, 2 * 16, 18 * 8, 16},
|
{6 * 8, 2 * 16, 17 * 8, 16},
|
||||||
""};
|
""};
|
||||||
Text text_duration{
|
Text text_duration{
|
||||||
{9 * 8, 3 * 16, 18 * 8, 16},
|
{9 * 8, 3 * 16, 20 * 8, 16},
|
||||||
""};
|
""};
|
||||||
|
Text text_bits_per_sample{
|
||||||
|
{0 * 8, 1 * 16, 2 * 8, 16},
|
||||||
|
"16"};
|
||||||
Button button_open{
|
Button button_open{
|
||||||
{24 * 8, 8, 6 * 8, 2 * 16},
|
{24 * 8, 8, 6 * 8, 2 * 16},
|
||||||
"Open"};
|
"Open"};
|
||||||
@ -122,32 +128,34 @@ class ViewWavView : public View {
|
|||||||
|
|
||||||
NumberField field_pos_seconds{
|
NumberField field_pos_seconds{
|
||||||
{9 * 8, 12 * 16},
|
{9 * 8, 12 * 16},
|
||||||
|
4,
|
||||||
|
{0, 0},
|
||||||
|
1,
|
||||||
|
' ',
|
||||||
|
true};
|
||||||
|
NumberField field_pos_milliseconds{
|
||||||
|
{14 * 8, 12 * 16},
|
||||||
3,
|
3,
|
||||||
{0, 999},
|
{0, 999},
|
||||||
1,
|
1,
|
||||||
' '};
|
'0',
|
||||||
|
true};
|
||||||
NumberField field_pos_samples{
|
NumberField field_pos_samples{
|
||||||
{14 * 8, 12 * 16},
|
|
||||||
6,
|
|
||||||
{0, 999999},
|
|
||||||
1,
|
|
||||||
'0'};
|
|
||||||
NumberField field_scale{
|
|
||||||
{28 * 8, 12 * 16},
|
|
||||||
2,
|
|
||||||
{1, 40},
|
|
||||||
1,
|
|
||||||
' '};
|
|
||||||
|
|
||||||
NumberField field_cursor_a{
|
|
||||||
{9 * 8, 13 * 16},
|
{9 * 8, 13 * 16},
|
||||||
3,
|
9,
|
||||||
{0, 239},
|
{0, 0},
|
||||||
|
1,
|
||||||
|
'0',
|
||||||
|
true};
|
||||||
|
NumberField field_scale{
|
||||||
|
{26 * 8, 12 * 16},
|
||||||
|
4,
|
||||||
|
{1, 9999},
|
||||||
1,
|
1,
|
||||||
' ',
|
' ',
|
||||||
true};
|
true};
|
||||||
|
|
||||||
NumberField field_cursor_b{
|
NumberField field_cursor_a{
|
||||||
{9 * 8, 14 * 16},
|
{9 * 8, 14 * 16},
|
||||||
3,
|
3,
|
||||||
{0, 239},
|
{0, 239},
|
||||||
@ -155,8 +163,16 @@ class ViewWavView : public View {
|
|||||||
' ',
|
' ',
|
||||||
true};
|
true};
|
||||||
|
|
||||||
|
NumberField field_cursor_b{
|
||||||
|
{9 * 8, 15 * 16},
|
||||||
|
3,
|
||||||
|
{0, 239},
|
||||||
|
1,
|
||||||
|
' ',
|
||||||
|
true};
|
||||||
|
|
||||||
Text text_delta{
|
Text text_delta{
|
||||||
{7 * 8, 15 * 16, 30 * 8, 16},
|
{7 * 8, 16 * 16, 30 * 8, 16},
|
||||||
"-"};
|
"-"};
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_replay_thread_error{
|
MessageHandlerRegistration message_handler_replay_thread_error{
|
||||||
|
@ -27,7 +27,7 @@ bool WAVFileReader::open(const std::filesystem::path& path) {
|
|||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
char ch;
|
char ch;
|
||||||
const uint8_t tag_INAM[4] = {'I', 'N', 'A', 'M'};
|
const uint8_t tag_INAM[4] = {'I', 'N', 'A', 'M'};
|
||||||
char title_buffer[32];
|
char title_buffer[32]{0};
|
||||||
uint32_t riff_size, data_end, title_size;
|
uint32_t riff_size, data_end, title_size;
|
||||||
size_t search_limit = 0;
|
size_t search_limit = 0;
|
||||||
|
|
||||||
@ -37,11 +37,17 @@ bool WAVFileReader::open(const std::filesystem::path& path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reinitialize to avoid old data when switching files
|
||||||
|
title_string = "";
|
||||||
|
sample_rate_ = 0;
|
||||||
|
bytes_per_sample = 0;
|
||||||
|
|
||||||
auto error = file_.open(path);
|
auto error = file_.open(path);
|
||||||
|
|
||||||
if (!error.is_valid()) {
|
if (!error.is_valid()) {
|
||||||
file_.read((void*)&header, sizeof(header)); // Read header (RIFF and WAVE)
|
file_.read((void*)&header, sizeof(header)); // Read header (RIFF and WAVE)
|
||||||
|
|
||||||
|
// TODO: Work needed here to process RIFF file format correctly, i.e. properly skip over LIST & INFO chunks
|
||||||
riff_size = header.cksize + 8;
|
riff_size = header.cksize + 8;
|
||||||
data_start = header.fmt.cksize + 28;
|
data_start = header.fmt.cksize + 28;
|
||||||
data_size_ = header.data.cksize;
|
data_size_ = header.data.cksize;
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
void AudioTXProcessor::execute(const buffer_c8_t& buffer) {
|
void AudioTXProcessor::execute(const buffer_c8_t& buffer) {
|
||||||
if (!configured) return;
|
if (!configured) return;
|
||||||
|
|
||||||
int32_t audio_sample_m;
|
buffer_s16_t audio_buffer{audio_data, AUDIO_OUTPUT_BUFFER_SIZE, sampling_rate};
|
||||||
|
int16_t audio_sample_s16;
|
||||||
|
|
||||||
// Zero-order hold (poop)
|
// Zero-order hold (poop)
|
||||||
for (size_t i = 0; i < buffer.count; i++) {
|
for (size_t i = 0; i < buffer.count; i++) {
|
||||||
@ -46,15 +47,16 @@ void AudioTXProcessor::execute(const buffer_c8_t& buffer) {
|
|||||||
|
|
||||||
if (bytes_per_sample == 1) {
|
if (bytes_per_sample == 1) {
|
||||||
sample = audio_sample - 0x80;
|
sample = audio_sample - 0x80;
|
||||||
audio_sample_m = sample * 256;
|
audio_sample_s16 = sample * 256;
|
||||||
} else {
|
} else {
|
||||||
audio_sample_m = audio_sample;
|
audio_sample_s16 = (int16_t)audio_sample;
|
||||||
|
sample = audio_sample_s16 / 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output to speaker too
|
// Output to speaker too
|
||||||
if (!tone_key_enabled) {
|
if (!tone_key_enabled) {
|
||||||
uint32_t imod32 = i & (AUDIO_OUTPUT_BUFFER_SIZE - 1);
|
uint32_t imod32 = i & (AUDIO_OUTPUT_BUFFER_SIZE - 1);
|
||||||
audio_data[imod32] = audio_sample_m;
|
audio_data[imod32] = audio_sample_s16;
|
||||||
if (imod32 == (AUDIO_OUTPUT_BUFFER_SIZE - 1))
|
if (imod32 == (AUDIO_OUTPUT_BUFFER_SIZE - 1))
|
||||||
audio_output.write_unprocessed(audio_buffer);
|
audio_output.write_unprocessed(audio_buffer);
|
||||||
}
|
}
|
||||||
@ -133,6 +135,7 @@ void AudioTXProcessor::replay_config(const ReplayConfigMessage& message) {
|
|||||||
|
|
||||||
void AudioTXProcessor::sample_rate_config(const SampleRateConfigMessage& message) {
|
void AudioTXProcessor::sample_rate_config(const SampleRateConfigMessage& message) {
|
||||||
resample_inc = (((uint64_t)message.sample_rate) << 16) / baseband_fs; // 16.16 fixed point message.sample_rate
|
resample_inc = (((uint64_t)message.sample_rate) << 16) / baseband_fs; // 16.16 fixed point message.sample_rate
|
||||||
|
sampling_rate = message.sample_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -51,11 +51,10 @@ class AudioTXProcessor : public BasebandProcessor {
|
|||||||
uint32_t audio_sample{};
|
uint32_t audio_sample{};
|
||||||
int32_t sample{0}, delta{};
|
int32_t sample{0}, delta{};
|
||||||
int8_t re{0}, im{0};
|
int8_t re{0}, im{0};
|
||||||
int8_t bytes_per_sample{1};
|
uint8_t bytes_per_sample{1};
|
||||||
int16_t audio_sample_s16{};
|
uint32_t sampling_rate{48000};
|
||||||
|
|
||||||
int16_t audio_data[AUDIO_OUTPUT_BUFFER_SIZE];
|
int16_t audio_data[AUDIO_OUTPUT_BUFFER_SIZE];
|
||||||
buffer_s16_t audio_buffer{audio_data, AUDIO_OUTPUT_BUFFER_SIZE, 48000};
|
|
||||||
AudioOutput audio_output{};
|
AudioOutput audio_output{};
|
||||||
|
|
||||||
size_t progress_interval_samples = 0, progress_samples = 0;
|
size_t progress_interval_samples = 0, progress_samples = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user