From d6cfcd3596eeae840d5e2fcdfdc4e77a3d2c8fbb Mon Sep 17 00:00:00 2001 From: moon2 <moon2protonmail@protonmail.com> Date: Sun, 11 Jun 2023 21:20:26 +0200 Subject: [PATCH] audio: line in api --- components/badge23/audio.c | 203 ++++++++++++++++----- components/badge23/include/badge23/audio.h | 43 ++++- components/badge23/include/badge23/synth.h | 17 +- components/badge23/spio.c | 22 +++ components/badge23/synth.c | 20 +- usermodule/mp_audio.c | 90 +++++++++ 6 files changed, 315 insertions(+), 80 deletions(-) diff --git a/components/badge23/audio.c b/components/badge23/audio.c index 9e0852547d..46aa8c8b6b 100644 --- a/components/badge23/audio.c +++ b/components/badge23/audio.c @@ -20,8 +20,8 @@ static void audio_player_task(void* arg); -#define DMA_BUFFER_SIZE 64 -#define DMA_BUFFER_COUNT 2 +#define DMA_BUFFER_SIZE 64*3 +#define DMA_BUFFER_COUNT 4 #define I2S_PORT 0 // used for exp(vol_dB * NAT_LOG_DB) @@ -49,6 +49,13 @@ const static float speaker_maximum_volume_system_dB = 14; static float speaker_maximum_volume_user_dB = speaker_maximum_volume_system_dB; static float speaker_minimum_volume_user_dB = speaker_maximum_volume_system_dB - 60; +static uint8_t input_source = AUDIO_INPUT_SOURCE_NONE; +static uint8_t headset_gain = 0; + +static int32_t input_thru_vol; +static int32_t input_thru_vol_int; +static int32_t input_thru_mute = 1; + uint8_t audio_headset_is_connected(){ return headset_connected; } uint8_t audio_headphones_are_connected(){ return headphones_connected || headphones_detection_override; } float audio_headphones_get_volume_dB(){ return headphones_volume_dB; } @@ -59,6 +66,8 @@ float audio_headphones_get_maximum_volume_dB(){ return headphones_maximum_volume float audio_speaker_get_maximum_volume_dB(){ return speaker_maximum_volume_user_dB; } uint8_t audio_headphones_get_mute(){ return headphones_mute ? 1 : 0; } uint8_t audio_speaker_get_mute(){ return speaker_mute ? 1 : 0; } +uint8_t audio_input_get_source(){ return input_source; } +uint8_t audio_headset_get_gain_dB(){ return headset_gain; } #if defined(CONFIG_BADGE23_HW_GEN_P3) || defined(CONFIG_BADGE23_HW_GEN_P4) || defined(CONFIG_BADGE23_HW_GEN_P6) @@ -91,6 +100,67 @@ static esp_err_t max98091_i2c_write_readback(const uint8_t reg, const uint8_t da return ret; } +void audio_headphones_line_in_set_hardware_thru(bool enable){ + max98091_i2c_write_readback(0x2B, (1<<5) | (1<<4)); // Enable Headphone Mixer + uint8_t trust_issue = enable ? 1 : 0; + max98091_i2c_write_readback(0x29, (trust_issue<<2) | (1<<1)); // Line A + DAC_L -> Left HP + max98091_i2c_write_readback(0x2A, (trust_issue<<3) | (1<<0)); // LIne B + DAC_R -> Right HP +} + + +void audio_speaker_line_in_set_hardware_thru(bool enable){ + uint8_t trust_issue = enable ? 1 : 0; + max98091_i2c_write_readback(0x2E, (trust_issue<<2) | (1<<1)); // Line A -> Left Speaker + max98091_i2c_write_readback(0x2F, (trust_issue<<3) | (1<<0)); // LIne B -> Right Speaker +} + + +void audio_line_in_set_hardware_thru(bool enable){ + audio_speaker_line_in_set_hardware_thru(enable); + audio_headphones_line_in_set_hardware_thru(enable); +} + +static void onboard_mic_set_power(bool enable){ + uint8_t trust_issue = enable ? 1 : 0; + max98091_i2c_write_readback(0x13, (1<<4) | (1<<5) | (trust_issue<<1) | (trust_issue<<0) ); +} + +#define ADC_MIXER_MIC_1 5 +#define ADC_MIXER_LINE_IN_B 4 +#define ADC_MIXER_LINE_IN_A 3 + +static void adc_left_set_mixer(uint8_t mask){ + max98091_i2c_write_readback(0x15, mask); +} + +static void adc_right_set_mixer(uint8_t mask){ + max98091_i2c_write_readback(0x16, mask); +} + +void audio_input_set_source(uint8_t source){ + if(source == AUDIO_INPUT_SOURCE_NONE){ + onboard_mic_set_power(0); + adc_left_set_mixer(0); + adc_right_set_mixer(0); + input_source = source; + } else if(source == AUDIO_INPUT_SOURCE_LINE_IN){ + onboard_mic_set_power(0); + adc_left_set_mixer(1<<ADC_MIXER_LINE_IN_A); + adc_right_set_mixer(1<<ADC_MIXER_LINE_IN_B); + input_source = source; + } else if(source == AUDIO_INPUT_SOURCE_HEADSET_MIC){ + onboard_mic_set_power(0); + adc_left_set_mixer(1<<ADC_MIXER_MIC_1); + adc_right_set_mixer(1<<ADC_MIXER_MIC_1); + input_source = source; + } else if(source == AUDIO_INPUT_SOURCE_ONBOARD_MIC){ + onboard_mic_set_power(1); + adc_left_set_mixer(0); + adc_right_set_mixer(0); + input_source = source; + } +} + static void init_codec() { // Enable CODEC @@ -103,7 +173,7 @@ static void init_codec() ESP_ERROR_CHECK(max98091_i2c_write_readback(0x1b, 1 << 4)); // pclk = mclk / 1 - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x26, (1 << 7) | (1 << 6))); // music, dc filter in record + ESP_ERROR_CHECK(max98091_i2c_write_readback(0x26, (1 << 7) | (1 << 6) | (1<<5))); // music, dc filter in record and playback ESP_ERROR_CHECK(max98091_i2c_write_readback(0x06, 1 << 2)); // Sets up DAI for left-justified slave mode operation. ESP_ERROR_CHECK(max98091_i2c_write_readback(0x07, 1 << 5)); // Sets up the DAC to speaker path @@ -116,47 +186,28 @@ static void init_codec() ESP_ERROR_CHECK(max98091_i2c_write_readback(0x42, 1 << 0)); // bandgap bias ESP_ERROR_CHECK(max98091_i2c_write_readback(0x43, 1 << 0)); // high performane mode - // Table 51. Digital Audio Interface (DAI) Format Configuration Register - - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x2E, 1)); // Left DAC -> Left Speaker - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x2F, 2)); // Right DAC -> Right Speaker - - //max98091_i2c_write_readback(0x2E, (1<<2) | (1<<1)); // Line A -> Left Speaker - //max98091_i2c_write_readback(0x2F, (1<<3) | (1<<0)); // LIne B -> Right Speaker - - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x29, 1)); // Left DAC -> Left HP - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x2A, 2)); // Right DAC -> Right HP - - // Mic bias is off ESP_ERROR_CHECK(max98091_i2c_write_readback(0x3E, (1<<4) |(1<<3) | (1<<2) | (1<<1) | (1<<0))); // enable micbias, line input amps, ADCs ESP_ERROR_CHECK(max98091_i2c_write_readback(0x0D, (1<<3) | (1<<2))); // IN3 SE -> Line A, IN4 SE -> Line B - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x15, (1<<4) )); // line B -> left ADC - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x16, (1<<3) )); // line A -> right ADC - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x44, (1<<2) | (1<<1) | (1<<0) )); // 128x oversampling, dithering, high performance ADC + //ESP_ERROR_CHECK(max98091_i2c_write_readback(0x44, (1<<2) | (1<<1) | (1<<0) )); // 128x oversampling, dithering, high performance ADC + ESP_ERROR_CHECK(max98091_i2c_write_readback(0x44, (1<<1) | (1<<0) )); // 64x oversampling, dithering, high performance ADC - max98091_i2c_write_readback(0x13, (1<<4) | (1<<5) | (1<<1) | (1<<0) ); // enable digital mic - - // Enable headset mic -#if 0 + // Enable headset mic preamp max98091_i2c_write_readback(0x13, 0); - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x0F, (0<<1) | (1<<0) )); // IN5/IN6 to MIC1 - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x10, (1<<6) | (1<<4) | (1<<2) )); // 20 dB gain on MIC1 - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x15, (1<<5) )); // MIC1 -> left ADC - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x16, (1<<5) )); // MIC1 -> right ADC -#endif + ESP_ERROR_CHECK(max98091_i2c_write_readback(0x0F, (1<<0) )); // IN5/IN6 to MIC1 + + audio_line_in_set_hardware_thru(0); + audio_headset_set_gain_dB(0); + audio_input_set_source(AUDIO_INPUT_SOURCE_NONE); + audio_input_thru_set_volume_dB(-20); //mute is on by default ESP_ERROR_CHECK(max98091_i2c_write_readback(0x3F, (1<<1) | (1<<0))); // output enable: enable dacs ESP_ERROR_CHECK(max98091_i2c_write_readback(0x45, 1<<7)); // power up - //max98091_i2c_write_readback(0x31, 0x2c); // 0db, no mute - //max98091_i2c_write_readback(0x32, 0x2c); // 0db, no mute ESP_ERROR_CHECK(max98091_i2c_write_readback(0x3F, (1<<7) | (1<<6) | (1<<5) | (1<<4) | (1<<1) | (1<<0))); // enable outputs, dacs //max98091_i2c_write_readback(0x27, (1<<4) | (1<<5)); // full playback gain - //max98091_i2c_write_readback(0x31, 0x3f); // +14 db speaker - //max98091_i2c_write_readback(0x32, 0x3f); // +14 db speaker - ESP_ERROR_CHECK(max98091_i2c_write_readback(0x41, 0x0)); + ESP_ERROR_CHECK(max98091_i2c_write_readback(0x41, 0x0)); // disable all digital filters except for dc blocking ESP_ERROR_CHECK(max98091_i2c_write_readback(0x3D, 1<<7)); // jack detect enable printf("4 readbacks failing here is normal dw ^w^\n"); @@ -167,13 +218,11 @@ static void i2s_init(void){ vTaskDelay(100 / portTICK_PERIOD_MS); // dunno if necessary static const i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, + .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX, .sample_rate = SAMPLE_RATE, .bits_per_sample = 16, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - //.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB, .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB, - //^...technically wrong but works...? in idf v5 it's msb but don't try that late at night .intr_alloc_flags = 0, // default interrupt priority .dma_buf_count = DMA_BUFFER_COUNT, .dma_buf_len = DMA_BUFFER_SIZE, @@ -184,9 +233,9 @@ static void i2s_init(void){ .mck_io_num = 18, .ws_io_num = 11, .data_out_num = 12, - .data_in_num = I2S_PIN_NO_CHANGE + .data_in_num = 13, }; - i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL); + ESP_ERROR_CHECK(i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL)); i2s_set_pin(I2S_PORT, &pin_config); @@ -257,6 +306,24 @@ void audio_speaker_set_mute(uint8_t mute){ audio_speaker_set_volume_dB(speaker_volume_dB); } +uint8_t audio_headset_set_gain_dB(uint8_t gain_dB){ + if(gain_dB < 0) gain_dB = 0; + if(gain_dB > 50) gain_dB = 50; + + uint8_t hi_bits = 0b01; + if(gain_dB > 30){ + gain_dB -= 30; + hi_bits = 0b11; + } else if(gain_dB > 20){ + gain_dB -= 20; + hi_bits = 0b10; + } + uint8_t reg = (hi_bits<<5) | (0x14-gain_dB); + max98091_i2c_write(0x10, reg); + headset_gain = gain_dB; + return headset_gain; +} + #elif defined(CONFIG_BADGE23_HW_GEN_P1) #define MAX_VOLUME_DB 10 @@ -318,6 +385,12 @@ void audio_speaker_set_mute(uint8_t mute){ } } +void audio_headphones_line_in_set_hardware_thru(bool enable){} +void audio_speaker_line_in_set_hardware_thru(bool enable){} +void audio_line_in_set_hardware_thru(bool enable){} +void audio_input_set_source(uint8_t source){} +uint8_t audio_headset_set_gain_dB(uint8_t gain_dB){} + #else #error "audio not implemented for this badge generation" #endif @@ -590,38 +663,68 @@ static void _audio_init(void) { // TODO: this assumes I2C is already initialized i2s_init(); audio_update_jacksense(); - //ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); TaskHandle_t handle; xTaskCreate(&audio_player_task, "Audio player", 3000, NULL, configMAX_PRIORITIES - 1, &handle); } +float audio_input_thru_set_volume_dB(float vol_dB){ + if(vol_dB > 0) vol_dB = 0; + input_thru_vol_int = (int32_t) (32768. * exp(vol_dB * NAT_LOG_DB)); + input_thru_vol = vol_dB; + return input_thru_vol; +} + +float audio_input_thru_get_volume_dB(){ return input_thru_vol; } +void audio_input_thru_set_mute(bool mute){ input_thru_mute = mute; } +bool audio_input_thru_get_mute(){ return input_thru_mute; } + static void audio_player_task(void* arg) { - int16_t buffer[DMA_BUFFER_SIZE * 2]; - memset(buffer, 0, sizeof(buffer)); + int16_t buffer_tx[DMA_BUFFER_SIZE * 2]; + int16_t buffer_rx[DMA_BUFFER_SIZE * 2]; + memset(buffer_tx, 0, sizeof(buffer_tx)); + memset(buffer_rx, 0, sizeof(buffer_rx)); + size_t count; while(true) { for(int i = 0; i < (DMA_BUFFER_SIZE * 2); i += 2){ - float sample = 0; + float acc = 0; + int32_t sample = 0; audio_source_t * audio_source = _audio_sources; while(audio_source != NULL){ - sample += (*(audio_source->render_function))(audio_source->render_data); + acc += (*(audio_source->render_function))(audio_source->render_data); audio_source = audio_source->next; } - st3m_scope_write((int16_t) (1600. * sample)); - sample = software_volume * (sample/10); + st3m_scope_write((int16_t) (1600. * acc)); + + sample += 32767 * acc; + sample = (sample * software_volume) >> 15; + if(sample > 32767) sample = 32767; if(sample < -32767) sample = -32767; - buffer[i] = (int16_t) sample; - buffer[i+1] = buffer[i]; + buffer_tx[i] = sample; + buffer_tx[i+1] = sample; + if(!input_thru_mute){ + buffer_tx[i] += (((int32_t) buffer_rx[i]) * input_thru_vol_int) >> 15; + buffer_tx[i+1] += (((int32_t) buffer_rx[i+1]) * input_thru_vol_int) >> 15; + } } - size_t count = 0; - i2s_write(I2S_PORT, buffer, sizeof(buffer), &count, 1000); - if (count != sizeof(buffer)) { - printf("i2s_write_bytes: count (%d) != length (%d)\n", count, sizeof(buffer)); + count = 0; + i2s_write(I2S_PORT, buffer_tx, sizeof(buffer_tx), &count, 1000); + if (count != sizeof(buffer_tx)) { + printf("i2s_write_bytes: count (%d) != length (%d)\n", count, sizeof(buffer_tx)); abort(); } + +#if defined(CONFIG_BADGE23_HW_GEN_P3) || defined(CONFIG_BADGE23_HW_GEN_P4) || defined(CONFIG_BADGE23_HW_GEN_P6) + count = 0; + i2s_read(I2S_PORT, buffer_rx, sizeof(buffer_rx), &count, 1000); + if (count != sizeof(buffer_rx)) { + printf("i2s_read_bytes: count (%d) != length (%d)\n", count, sizeof(buffer_rx)); + abort(); + } +#endif } } diff --git a/components/badge23/include/badge23/audio.h b/components/badge23/include/badge23/audio.h index 813a782bea..93ee3edf81 100644 --- a/components/badge23/include/badge23/audio.h +++ b/components/badge23/include/badge23/audio.h @@ -1,7 +1,13 @@ #pragma once #include <stdint.h> +#include <stdbool.h> -#define SAMPLE_RATE 16000 +#define SAMPLE_RATE 48000 + +#define AUDIO_INPUT_SOURCE_NONE 0 +#define AUDIO_INPUT_SOURCE_LINE_IN 1 +#define AUDIO_INPUT_SOURCE_HEADSET_MIC 2 +#define AUDIO_INPUT_SOURCE_ONBOARD_MIC 3 /* Initializes I2S bus, the audio task and required data structures. * Expects an initialized I2C bus, will fail ungracefully otherwise (TODO). @@ -119,6 +125,41 @@ float audio_get_volume_relative(); * is chosen, else the "speaker" variant is chosen. */ +/* These route whatever is on the line in port directly to the headphones or + * speaker respectively (enable = 1), or don't (enable = 0). Is affected by mute + * and coarse hardware volume settings, however software fine volume is not applied. + * + * Good for testing, might deprecate later, idk~ + */ +void audio_headphones_line_in_set_hardware_thru(bool enable); +void audio_speaker_line_in_set_hardware_thru(bool enable); +void audio_line_in_set_hardware_thru(bool enable); + +/* The codec can transmit audio data from different sources. This function enables + * one or no source as provided by the AUDIO_INPUT_SOURCE_* constants. + * + * Note: The onboard digital mic turns on an LED on the top board if it receives + * a clock signal which is considered a good proxy for its capability of reading data. + * + * TODO: check if sources are available + */ +void audio_input_set_source(uint8_t source); + +/* Returns the currently selected input source. + */ +uint8_t audio_input_get_source(); + +/* Hardware preamp gain + */ +uint8_t audio_headset_set_gain_dB(uint8_t gain_dB); +uint8_t audio_headset_get_gain_dB(); + +float audio_input_thru_set_volume_dB(float vol_dB); +float audio_input_thru_get_volume_dB(); +void audio_input_thru_set_mute(bool mute); +bool audio_input_thru_get_mute(); + + /* HEADPHONE PORT POLICY diff --git a/components/badge23/include/badge23/synth.h b/components/badge23/include/badge23/synth.h index 50f52fcd5a..cd52e28bd8 100644 --- a/components/badge23/include/badge23/synth.h +++ b/components/badge23/include/badge23/synth.h @@ -27,26 +27,11 @@ typedef struct { int8_t overflow_event; //set to -1 when counter underflows (below -1), //set to +1 when counter overflows (above 1) //not reset or used by anything so far + uint8_t undersampling_counter; uint16_t noise_reg; } trad_osc_t; -//#define KS_BUFFER_SIZE (SAMPLE_RATE)/20 -#define KS_BUFFER_SIZE 800 - -typedef struct { - //user variables - float freq; //frequency in hertz, negative frequencies are rectified, - //minimum freq determined by KS_BUFFER_SIZE - float feedback; //feedback value, will be compensated with frequency - //for equal decay across spectrum, [-1..1] without - - //internal data storage, not for user access - float tape[KS_BUFFER_SIZE]; //the delay chain - float real_feedback; //compensated feedback value -} ks_osc_t; //karplus strong - float run_trad_osc(trad_osc_t * osc); - void trad_osc_set_freq_semitone(trad_osc_t * osc, float bend); void trad_osc_set_freq_Hz(trad_osc_t * osc, float freq); void trad_osc_set_waveform(trad_osc_t * osc, uint8_t waveform); diff --git a/components/badge23/spio.c b/components/badge23/spio.c index c405026cc7..f57c80c865 100644 --- a/components/badge23/spio.c +++ b/components/badge23/spio.c @@ -52,11 +52,17 @@ #define LEFT_BUTTON_LEFT (7+8) #define RIGHT_BUTTON_RIGHT (5+8) +#define LINE_IN_JACKSENSE (6+8) +#define CHARGER_STATE (2+8) + #endif static int8_t leftbutton = 0; static int8_t rightbutton = 0; +static bool line_in_jacksense = 1; +static bool charger_state; + static bool menu_button_left = 0; static uint8_t badge_link_enabled = 0; @@ -295,6 +301,9 @@ void update_button_state(){ uint8_t rm = gpio_get_level(RIGHT_BUTTON_MID); uint8_t lm = gpio_get_level(LEFT_BUTTON_MID); + line_in_jacksense = max7321s_get_pin(LINE_IN_JACKSENSE); + charger_state = max7321s_get_pin(CHARGER_STATE); + int8_t new_rightbutton = process_button_state(rr, rm, rl); int8_t new_leftbutton = process_button_state(lr, lm, ll); if(new_rightbutton != rightbutton){ @@ -325,6 +334,19 @@ int8_t get_button_state(bool left){ return rightbutton; } +bool spio_charger_state_get(){ +#ifdef ALWAYS_UPDATE_BUTTON + update_button_state(); +#endif + return charger_state; +} + +bool spio_line_in_jacksense_get(){ +#ifdef ALWAYS_UPDATE_BUTTON + update_button_state(); +#endif + return line_in_jacksense; +} void spio_menu_button_set_left(bool left){ menu_button_left = 1; diff --git a/components/badge23/synth.c b/components/badge23/synth.c index 52ce89fb55..fe0d81ade6 100644 --- a/components/badge23/synth.c +++ b/components/badge23/synth.c @@ -2,17 +2,8 @@ #include "badge23/audio.h" #include <math.h> -float ks_osc(ks_osc_t * ks, float input){ - //TODO: FIX THIS - ks->real_feedback = ks->feedback; - - float delay_time = ((float) (SAMPLE_RATE))/ks->freq; - if(delay_time >= (KS_BUFFER_SIZE)) delay_time = (KS_BUFFER_SIZE) - 1; - - - //ks->tape[0] = input + real_feedback * ks->tape[delay_time]; - return ks->tape[0]; -} +#define SYNTH_UNDERSAMPLING 3 +#define SYNTH_SAMPLE_RATE ((SAMPLE_RATE)/(SYNTH_UNDERSAMPLING)) float waveshaper(uint8_t shape, float in); float nes_noise(uint16_t * reg, uint8_t mode, uint8_t run); @@ -64,16 +55,19 @@ void run_trad_env(trad_osc_t * osc){ } float run_trad_osc(trad_osc_t * osc){ + static float ret = 0; + osc->undersampling_counter = (osc->undersampling_counter+1) % SYNTH_UNDERSAMPLING; + if(osc->undersampling_counter) return ret; + run_trad_env(osc); if(!osc->env_phase) return 0; - float ret = 0; //run core sawtooth float freq = osc->freq * osc->bend; if(freq > 10000) freq = 10000; if(freq < -10000) freq = -10000; if(freq != freq) freq = 0; - osc->counter += 2. * freq / ((float)(SAMPLE_RATE)); + osc->counter += 2. * freq / ((float)(SYNTH_SAMPLE_RATE)); if(osc->counter != osc->counter){ printf("trad_osc counter is NaN"); abort(); diff --git a/usermodule/mp_audio.c b/usermodule/mp_audio.c index 2634c1a831..145216b211 100644 --- a/usermodule/mp_audio.c +++ b/usermodule/mp_audio.c @@ -181,6 +181,76 @@ STATIC mp_obj_t mp_get_volume_relative() { STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_get_volume_relative_obj, mp_get_volume_relative); + +STATIC mp_obj_t mp_headphones_line_in_set_hardware_thru(mp_obj_t enable) { + audio_headphones_line_in_set_hardware_thru(mp_obj_get_int(enable)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_headphones_line_in_set_hardware_thru_obj, mp_headphones_line_in_set_hardware_thru); + +STATIC mp_obj_t mp_speaker_line_in_set_hardware_thru(mp_obj_t enable) { + audio_speaker_line_in_set_hardware_thru(mp_obj_get_int(enable)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_speaker_line_in_set_hardware_thru_obj, mp_speaker_line_in_set_hardware_thru); + +STATIC mp_obj_t mp_line_in_set_hardware_thru(mp_obj_t enable) { + audio_line_in_set_hardware_thru(mp_obj_get_int(enable)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_line_in_set_hardware_thru_obj, mp_line_in_set_hardware_thru); + + + +STATIC mp_obj_t mp_input_set_source(mp_obj_t enable) { + audio_input_set_source(mp_obj_get_int(enable)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_input_set_source_obj, mp_input_set_source); + +STATIC mp_obj_t mp_input_get_source(mp_obj_t enable) { + return mp_obj_new_int(audio_input_get_source()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_input_get_source_obj, mp_input_get_source); + + + +STATIC mp_obj_t mp_headset_set_gain_dB(mp_obj_t gain_dB) { + audio_headset_set_gain_dB(mp_obj_get_int(gain_dB)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_headset_set_gain_dB_obj, mp_headset_set_gain_dB); + +STATIC mp_obj_t mp_headset_get_gain_dB(mp_obj_t enable) { + return mp_obj_new_int(audio_headset_get_gain_dB()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_headset_get_gain_dB_obj, mp_headset_get_gain_dB); + + + +STATIC mp_obj_t mp_input_thru_set_volume_dB(mp_obj_t vol_dB) { + return mp_obj_new_float(audio_input_thru_set_volume_dB(mp_obj_get_float(vol_dB))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_input_thru_set_volume_dB_obj, mp_input_thru_set_volume_dB); + +STATIC mp_obj_t mp_input_thru_get_volume_dB() { + return mp_obj_new_float(audio_input_thru_get_volume_dB()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_input_thru_get_volume_dB_obj, mp_input_thru_get_volume_dB); + +STATIC mp_obj_t mp_input_thru_set_mute(mp_obj_t mute) { + audio_input_thru_set_mute(mp_obj_get_int(mute)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_input_thru_set_mute_obj, mp_input_thru_set_mute); + +STATIC mp_obj_t mp_input_thru_get_mute() { + return mp_obj_new_int(audio_input_thru_get_mute()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_input_thru_get_mute_obj, mp_input_thru_get_mute); + + + STATIC const mp_rom_map_elem_t mp_module_audio_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audio) }, { MP_ROM_QSTR(MP_QSTR_headset_is_connected), MP_ROM_PTR(&mp_headset_is_connected_obj) }, @@ -220,6 +290,26 @@ STATIC const mp_rom_map_elem_t mp_module_audio_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_headphones_get_volume_relative), MP_ROM_PTR(&mp_headphones_get_volume_relative_obj) }, { MP_ROM_QSTR(MP_QSTR_speaker_get_volume_relative), MP_ROM_PTR(&mp_speaker_get_volume_relative_obj) }, { MP_ROM_QSTR(MP_QSTR_get_volume_relative), MP_ROM_PTR(&mp_get_volume_relative_obj) }, + + { MP_ROM_QSTR(MP_QSTR_headphones_line_in_set_hardware_thru), MP_ROM_PTR(&mp_headphones_line_in_set_hardware_thru_obj) }, + { MP_ROM_QSTR(MP_QSTR_speaker_line_in_set_hardware_thru), MP_ROM_PTR(&mp_speaker_line_in_set_hardware_thru_obj) }, + { MP_ROM_QSTR(MP_QSTR_line_in_set_hardware_thru), MP_ROM_PTR(&mp_line_in_set_hardware_thru_obj) }, + + { MP_ROM_QSTR(MP_QSTR_input_set_source), MP_ROM_PTR(&mp_input_set_source_obj) }, + { MP_ROM_QSTR(MP_QSTR_input_get_source), MP_ROM_PTR(&mp_input_get_source_obj) }, + + { MP_ROM_QSTR(MP_QSTR_headset_set_gain_dB), MP_ROM_PTR(&mp_headset_set_gain_dB_obj) }, + { MP_ROM_QSTR(MP_QSTR_headset_get_gain_dB), MP_ROM_PTR(&mp_headset_get_gain_dB_obj) }, + + { MP_ROM_QSTR(MP_QSTR_input_thru_set_volume_dB), MP_ROM_PTR(&mp_input_thru_set_volume_dB_obj) }, + { MP_ROM_QSTR(MP_QSTR_input_thru_get_volume_dB), MP_ROM_PTR(&mp_input_thru_get_volume_dB_obj) }, + { MP_ROM_QSTR(MP_QSTR_input_thru_set_mute), MP_ROM_PTR(&mp_input_thru_set_mute_obj) }, + { MP_ROM_QSTR(MP_QSTR_input_thru_get_mute), MP_ROM_PTR(&mp_input_thru_get_mute_obj) }, + + { MP_ROM_QSTR(MP_QSTR_INPUT_SOURCE_NONE), MP_ROM_INT(AUDIO_INPUT_SOURCE_NONE) }, + { MP_ROM_QSTR(MP_QSTR_INPUT_SOURCE_LINE_IN), MP_ROM_INT(AUDIO_INPUT_SOURCE_LINE_IN) }, + { MP_ROM_QSTR(MP_QSTR_INPUT_SOURCE_HEADSET_MIC), MP_ROM_INT(AUDIO_INPUT_SOURCE_HEADSET_MIC) }, + { MP_ROM_QSTR(MP_QSTR_INPUT_SOURCE_ONBOARD_MIC), MP_ROM_INT(AUDIO_INPUT_SOURCE_ONBOARD_MIC) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_audio_globals, mp_module_audio_globals_table); -- GitLab