mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 14:59:24 -05:00
Extract LOTS of stuff into an audio API.
Prevent all manner of type and implementation leakage.
This commit is contained in:
parent
1b793da17f
commit
0294165481
@ -25,8 +25,7 @@
|
||||
#include "portapack_shared_memory.hpp"
|
||||
using namespace portapack;
|
||||
|
||||
#include "i2s.hpp"
|
||||
using namespace lpc43xx;
|
||||
#include "audio.hpp"
|
||||
|
||||
#include "utility.hpp"
|
||||
|
||||
@ -128,20 +127,20 @@ AnalogAudioView::AnalogAudioView(
|
||||
this->on_show_options_modulation();
|
||||
};
|
||||
|
||||
field_volume.set_value((receiver_model.headphone_volume() - wolfson::wm8731::headphone_gain_range.max).decibel() + 99);
|
||||
field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99);
|
||||
field_volume.on_change = [this](int32_t v) {
|
||||
this->on_headphone_volume_changed(v);
|
||||
};
|
||||
|
||||
audio::output::start();
|
||||
|
||||
update_modulation(static_cast<ReceiverModel::Mode>(modulation));
|
||||
}
|
||||
|
||||
AnalogAudioView::~AnalogAudioView() {
|
||||
// TODO: Manipulating audio codec here, and in ui_receiver.cpp. Good to do
|
||||
// both?
|
||||
i2s::i2s0::tx_mute();
|
||||
|
||||
audio_codec.headphone_mute();
|
||||
audio::output::stop();
|
||||
|
||||
receiver_model.disable();
|
||||
}
|
||||
@ -286,11 +285,13 @@ void AnalogAudioView::on_reference_ppm_correction_changed(int32_t v) {
|
||||
}
|
||||
|
||||
void AnalogAudioView::on_headphone_volume_changed(int32_t v) {
|
||||
const auto new_volume = volume_t::decibel(v - 99) + wolfson::wm8731::headphone_gain_range.max;
|
||||
const auto new_volume = volume_t::decibel(v - 99) + audio::headphone::volume_range().max;
|
||||
receiver_model.set_headphone_volume(new_volume);
|
||||
}
|
||||
|
||||
void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
||||
audio::output::mute();
|
||||
|
||||
const auto is_wideband_spectrum_mode = (modulation == ReceiverModel::Mode::SpectrumAnalysis);
|
||||
receiver_model.set_baseband_configuration({
|
||||
.mode = toUType(modulation),
|
||||
@ -300,7 +301,9 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
||||
receiver_model.set_baseband_bandwidth(is_wideband_spectrum_mode ? 12000000 : 1750000);
|
||||
receiver_model.enable();
|
||||
|
||||
i2s::i2s0::tx_unmute();
|
||||
if( !is_wideband_spectrum_mode ) {
|
||||
audio::output::unmute();
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
|
@ -21,6 +21,154 @@
|
||||
|
||||
#include "audio.hpp"
|
||||
|
||||
#include "portapack.hpp"
|
||||
using portapack::i2c0;
|
||||
using portapack::clock_manager;
|
||||
|
||||
#include "wm8731.hpp"
|
||||
using wolfson::wm8731::WM8731;
|
||||
|
||||
#include "i2s.hpp"
|
||||
using namespace lpc43xx;
|
||||
|
||||
namespace audio {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr i2s::ConfigTX i2s0_config_tx {
|
||||
.dao = i2s::DAO {
|
||||
.wordwidth = i2s::WordWidth::Bits16,
|
||||
.mono = 0,
|
||||
.stop = 1,
|
||||
.reset = 0,
|
||||
.ws_sel = 0,
|
||||
.ws_halfperiod = 0x0f,
|
||||
.mute = 1,
|
||||
},
|
||||
.txrate = i2s::MCLKRate {
|
||||
.x_divider = 0,
|
||||
.y_divider = 0,
|
||||
},
|
||||
.txbitrate = i2s::BitRate {
|
||||
.bitrate = 7,
|
||||
},
|
||||
.txmode = i2s::Mode {
|
||||
.clksel = i2s::ClockSelect::BaseAudioClkOrExternalMCLK,
|
||||
.four_pin = 0,
|
||||
.mclk_out_en = 1,
|
||||
},
|
||||
};
|
||||
|
||||
constexpr i2s::ConfigRX i2s0_config_rx {
|
||||
.dai = i2s::DAI {
|
||||
.wordwidth = i2s::WordWidth::Bits16,
|
||||
.mono = 0,
|
||||
.stop = 1,
|
||||
.reset = 0,
|
||||
.ws_sel = 1,
|
||||
.ws_halfperiod = 0x0f,
|
||||
},
|
||||
.rxrate = i2s::MCLKRate {
|
||||
.x_divider = 0,
|
||||
.y_divider = 0,
|
||||
},
|
||||
.rxbitrate = i2s::BitRate {
|
||||
.bitrate = 7,
|
||||
},
|
||||
.rxmode = i2s::Mode {
|
||||
.clksel = i2s::ClockSelect::BaseAudioClkOrExternalMCLK,
|
||||
.four_pin = 1,
|
||||
.mclk_out_en = 0,
|
||||
},
|
||||
};
|
||||
|
||||
constexpr i2s::ConfigDMA i2s0_config_dma {
|
||||
.dma1 = i2s::DMA {
|
||||
.rx_enable = 1,
|
||||
.tx_enable = 0,
|
||||
.rx_depth = 4,
|
||||
.tx_depth = 0,
|
||||
},
|
||||
.dma2 = i2s::DMA {
|
||||
.rx_enable = 0,
|
||||
.tx_enable = 1,
|
||||
.rx_depth = 0,
|
||||
.tx_depth = 4,
|
||||
},
|
||||
};
|
||||
|
||||
constexpr uint8_t wm8731_i2c_address = 0x1a;
|
||||
|
||||
WM8731 audio_codec { i2c0, wm8731_i2c_address };
|
||||
|
||||
} /* namespace */
|
||||
|
||||
namespace output {
|
||||
|
||||
void start() {
|
||||
i2s::i2s0::tx_start();
|
||||
unmute();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
mute();
|
||||
i2s::i2s0::tx_stop();
|
||||
}
|
||||
|
||||
void mute() {
|
||||
i2s::i2s0::tx_mute();
|
||||
|
||||
audio_codec.headphone_mute();
|
||||
}
|
||||
|
||||
void unmute() {
|
||||
i2s::i2s0::tx_unmute();
|
||||
}
|
||||
|
||||
} /* namespace output */
|
||||
|
||||
namespace headphone {
|
||||
|
||||
volume_range_t volume_range() {
|
||||
return wolfson::wm8731::headphone_gain_range;
|
||||
}
|
||||
|
||||
void set_volume(const volume_t volume) {
|
||||
audio_codec.set_headphone_volume(volume);
|
||||
}
|
||||
|
||||
} /* namespace headphone */
|
||||
|
||||
namespace debug {
|
||||
|
||||
int reg_count() {
|
||||
return wolfson::wm8731::reg_count;
|
||||
}
|
||||
|
||||
uint16_t reg_read(const int register_number) {
|
||||
return audio_codec.read(register_number);
|
||||
}
|
||||
|
||||
} /* namespace debug */
|
||||
|
||||
void init() {
|
||||
clock_manager.start_audio_pll();
|
||||
audio_codec.init();
|
||||
|
||||
i2s::i2s0::configure(
|
||||
i2s0_config_tx,
|
||||
i2s0_config_rx,
|
||||
i2s0_config_dma
|
||||
);
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
audio_codec.reset();
|
||||
output::stop();
|
||||
}
|
||||
|
||||
void set_rate(const Rate rate) {
|
||||
clock_manager.set_base_audio_clock_divider(toUType(rate));
|
||||
}
|
||||
|
||||
} /* namespace audio */
|
||||
|
@ -22,72 +22,47 @@
|
||||
#ifndef __AUDIO_H__
|
||||
#define __AUDIO_H__
|
||||
|
||||
#include "i2s.hpp"
|
||||
using namespace lpc43xx;
|
||||
#include "volume.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace audio {
|
||||
|
||||
constexpr i2s::ConfigTX i2s0_config_tx {
|
||||
.dao = i2s::DAO {
|
||||
.wordwidth = i2s::WordWidth::Bits16,
|
||||
.mono = 0,
|
||||
.stop = 1,
|
||||
.reset = 0,
|
||||
.ws_sel = 0,
|
||||
.ws_halfperiod = 0x0f,
|
||||
.mute = 1,
|
||||
},
|
||||
.txrate = i2s::MCLKRate {
|
||||
.x_divider = 0,
|
||||
.y_divider = 0,
|
||||
},
|
||||
.txbitrate = i2s::BitRate {
|
||||
.bitrate = 7,
|
||||
},
|
||||
.txmode = i2s::Mode {
|
||||
.clksel = i2s::ClockSelect::BaseAudioClkOrExternalMCLK,
|
||||
.four_pin = 0,
|
||||
.mclk_out_en = 1,
|
||||
},
|
||||
namespace output {
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void mute();
|
||||
void unmute();
|
||||
|
||||
} /* namespace output */
|
||||
|
||||
namespace headphone {
|
||||
|
||||
volume_range_t volume_range();
|
||||
|
||||
void set_volume(const volume_t volume);
|
||||
|
||||
} /* namespace headphone */
|
||||
|
||||
namespace debug {
|
||||
|
||||
int reg_count();
|
||||
uint16_t reg_read(const int register_number);
|
||||
|
||||
} /* namespace debug */
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
|
||||
enum class Rate {
|
||||
Hz_12000 = 4,
|
||||
Hz_24000 = 2,
|
||||
Hz_48000 = 1,
|
||||
};
|
||||
|
||||
constexpr i2s::ConfigRX i2s0_config_rx {
|
||||
.dai = i2s::DAI {
|
||||
.wordwidth = i2s::WordWidth::Bits16,
|
||||
.mono = 0,
|
||||
.stop = 1,
|
||||
.reset = 0,
|
||||
.ws_sel = 1,
|
||||
.ws_halfperiod = 0x0f,
|
||||
},
|
||||
.rxrate = i2s::MCLKRate {
|
||||
.x_divider = 0,
|
||||
.y_divider = 0,
|
||||
},
|
||||
.rxbitrate = i2s::BitRate {
|
||||
.bitrate = 7,
|
||||
},
|
||||
.rxmode = i2s::Mode {
|
||||
.clksel = i2s::ClockSelect::BaseAudioClkOrExternalMCLK,
|
||||
.four_pin = 1,
|
||||
.mclk_out_en = 0,
|
||||
},
|
||||
};
|
||||
|
||||
constexpr i2s::ConfigDMA i2s0_config_dma {
|
||||
.dma1 = i2s::DMA {
|
||||
.rx_enable = 1,
|
||||
.tx_enable = 0,
|
||||
.rx_depth = 4,
|
||||
.tx_depth = 0,
|
||||
},
|
||||
.dma2 = i2s::DMA {
|
||||
.rx_enable = 0,
|
||||
.tx_enable = 1,
|
||||
.rx_depth = 0,
|
||||
.tx_depth = 4,
|
||||
},
|
||||
};
|
||||
void set_rate(const Rate rate);
|
||||
|
||||
} /* namespace audio */
|
||||
|
||||
|
@ -50,8 +50,6 @@ I2C i2c0(&I2CD0);
|
||||
SPI ssp0(&SPID1);
|
||||
SPI ssp1(&SPID2);
|
||||
|
||||
wolfson::wm8731::WM8731 audio_codec { i2c0, portapack::wm8731_i2c_address };
|
||||
|
||||
si5351::Si5351 clock_generator {
|
||||
i2c0, hackrf::one::si5351_i2c_address
|
||||
};
|
||||
@ -129,17 +127,8 @@ void init() {
|
||||
clock_manager.set_reference_ppb(persistent_memory::correction_ppb());
|
||||
clock_manager.run_at_full_speed();
|
||||
|
||||
clock_manager.start_audio_pll();
|
||||
audio_codec.init();
|
||||
|
||||
i2s::i2s0::configure(
|
||||
audio::i2s0_config_tx,
|
||||
audio::i2s0_config_rx,
|
||||
audio::i2s0_config_dma
|
||||
);
|
||||
i2s::i2s0::tx_start();
|
||||
i2s::i2s0::rx_start();
|
||||
|
||||
audio::init();
|
||||
|
||||
clock_manager.enable_first_if_clock();
|
||||
clock_manager.enable_second_if_clock();
|
||||
clock_manager.enable_codec_clocks();
|
||||
@ -152,7 +141,7 @@ void shutdown() {
|
||||
display.shutdown();
|
||||
|
||||
radio::disable();
|
||||
audio_codec.reset();
|
||||
audio::shutdown();
|
||||
clock_manager.shutdown();
|
||||
|
||||
power.shutdown();
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include "i2c_pp.hpp"
|
||||
#include "spi_pp.hpp"
|
||||
#include "wm8731.hpp"
|
||||
#include "si5351.hpp"
|
||||
#include "lcd_ili9341.hpp"
|
||||
|
||||
@ -43,8 +42,6 @@ extern I2C i2c0;
|
||||
extern SPI ssp0;
|
||||
extern SPI ssp1;
|
||||
|
||||
extern wolfson::wm8731::WM8731 audio_codec;
|
||||
|
||||
extern si5351::Si5351 clock_generator;
|
||||
extern ClockManager clock_manager;
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "portapack.hpp"
|
||||
using namespace portapack;
|
||||
|
||||
#include "audio.hpp"
|
||||
|
||||
#include "dsp_fir_taps.hpp"
|
||||
#include "dsp_iir.hpp"
|
||||
#include "dsp_iir_config.hpp"
|
||||
@ -62,7 +64,7 @@ void AMConfig::apply() const {
|
||||
audio_12k_hpf_300hz_config
|
||||
};
|
||||
shared_memory.baseband_queue.push(message);
|
||||
clock_manager.set_base_audio_clock_divider(4);
|
||||
audio::set_rate(audio::Rate::Hz_12000);
|
||||
}
|
||||
|
||||
void NBFMConfig::apply() const {
|
||||
@ -76,7 +78,7 @@ void NBFMConfig::apply() const {
|
||||
audio_24k_deemph_300_6_config
|
||||
};
|
||||
shared_memory.baseband_queue.push(message);
|
||||
clock_manager.set_base_audio_clock_divider(2);
|
||||
audio::set_rate(audio::Rate::Hz_24000);
|
||||
}
|
||||
|
||||
void WFMConfig::apply() const {
|
||||
@ -89,7 +91,7 @@ void WFMConfig::apply() const {
|
||||
audio_48k_deemph_2122_6_config
|
||||
};
|
||||
shared_memory.baseband_queue.push(message);
|
||||
clock_manager.set_base_audio_clock_divider(1);
|
||||
audio::set_rate(audio::Rate::Hz_48000);
|
||||
}
|
||||
|
||||
static constexpr std::array<AMConfig, 3> am_configs { {
|
||||
@ -314,7 +316,7 @@ void ReceiverModel::update_headphone_volume() {
|
||||
// TODO: Manipulating audio codec here, and in ui_receiver.cpp. Good to do
|
||||
// both?
|
||||
|
||||
audio_codec.set_headphone_volume(headphone_volume_);
|
||||
audio::headphone::set_volume(headphone_volume_);
|
||||
}
|
||||
|
||||
void ReceiverModel::update_modulation_configuration() {
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "radio.hpp"
|
||||
#include "string_format.hpp"
|
||||
|
||||
#include "audio.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
/* DebugMemoryView *******************************************************/
|
||||
@ -260,8 +262,8 @@ DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
[](const size_t register_number) { return portapack::clock_generator.read_register(register_number); }
|
||||
); } },
|
||||
{ "WM8731", [&nav](){ nav.push<RegistersView>(
|
||||
"WM8731", RegistersWidgetConfig { wolfson::wm8731::reg_count, 1, 3, 4 },
|
||||
[](const size_t register_number) { return portapack::audio_codec.read(register_number); }
|
||||
"WM8731", RegistersWidgetConfig { audio::debug::reg_count(), 1, 3, 4 },
|
||||
[](const size_t register_number) { return audio::debug::reg_read(register_number); }
|
||||
); } },
|
||||
{ "Temperature", [&nav](){ nav.push<TemperatureView>(); } },
|
||||
} });
|
||||
|
@ -56,10 +56,6 @@ constexpr GPIO gpio_cpld_tdo = gpio[GPIO1_8]; // P1_5
|
||||
constexpr GPIO gpio_cpld_tck = gpio[GPIO3_0]; // P6_1
|
||||
constexpr GPIO gpio_cpld_tdi = gpio[GPIO3_1]; // P6_2
|
||||
|
||||
/* I2C0 */
|
||||
|
||||
constexpr uint8_t wm8731_i2c_address = 0x1a;
|
||||
|
||||
} /* namespace portapack */
|
||||
|
||||
#endif/*__PORTAPACK_HAL_H__*/
|
||||
|
Loading…
Reference in New Issue
Block a user