Загрузка данных


	/* 2. TX Playback Config */
	audio_cfg.dai_route = AUDIO_ROUTE_PLAYBACK;
	audio_cfg.dai_cfg.i2s.word_size = SAMPLE_BIT_WIDTH_TX;
	audio_cfg.dai_cfg.i2s.frame_clk_freq = SAMPLE_FREQ_TX;
	audio_cfg.dai_cfg.i2s.mem_slab = &mem_slab_tx;
	audio_cfg.dai_cfg.i2s.block_size = BLOCK_SIZE_TX;
	audio_codec_configure(tx_dev, &audio_cfg);
	k_msleep(500);

	if (!init_buttons()) return 0;

	if (!device_is_ready(i2s_dev_rx) || !device_is_ready(i2s_dev_tx)) {
		printk("SAI2 Devices are not ready\n");
		return 0;
	}

	/* 3. Setings for I2S/SAI */
	config_rx.word_size = SAMPLE_BIT_WIDTH_RX;
	config_rx.channels = NUMBER_OF_CHANNELS;
	config_rx.format = I2S_FMT_DATA_FORMAT_I2S;
	config_rx.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER;
	config_rx.timeout = TIMEOUT;

	/* RX I2S config */
	config_rx.frame_clk_freq = SAMPLE_FREQ_RX; 
	config_rx.mem_slab = &mem_slab_rx;
	config_rx.block_size = BLOCK_SIZE_RX;
	i2s_configure(i2s_dev_rx, I2S_DIR_RX, &config_rx);

	/* TX I2S config  */
	config_tx = config_rx;
	config_tx.word_size = SAMPLE_BIT_WIDTH_TX;
	config_tx.frame_clk_freq = SAMPLE_FREQ_TX;
	config_tx.mem_slab = &mem_slab_tx;
	config_tx.block_size = BLOCK_SIZE_TX;
	i2s_configure(i2s_dev_tx, I2S_DIR_TX, &config_tx);

#ifndef MY_CODE
	/* 1. Set explicit volume to safe maximum level (100%) */
	audio_property_value_t vol_val = { .vol = 100 };
	audio_codec_set_property(tx_dev, AUDIO_PROPERTY_OUTPUT_VOLUME, AUDIO_CHANNEL_ALL, vol_val);
	audio_codec_set_property(rx_dev, AUDIO_PROPERTY_INPUT_VOLUME, AUDIO_CHANNEL_ALL, vol_val);
	
	/* 2. Explicitly disable output channel mutes */
	audio_property_value_t mute_val = { .mute = false };
	audio_codec_set_property(tx_dev, AUDIO_PROPERTY_OUTPUT_MUTE, AUDIO_CHANNEL_ALL, mute_val);
	audio_codec_set_property(rx_dev, AUDIO_PROPERTY_INPUT_MUTE, AUDIO_CHANNEL_ALL, mute_val);

	audio_codec_start_output(rx_dev);
#endif

	/* 4. Main cycle */
	while (1) {
		k_sem_take(&toggle_transfer, K_FOREVER);

		if (!streaming) {
			if (!prepare_transfer(i2s_dev_rx, i2s_dev_tx)) {
				printk("Failed to prepare TX buffers\n");
				continue;
			}
			if (!trigger_command(i2s_dev_rx, i2s_dev_tx, I2S_TRIGGER_START)) {
				continue;
			}
			streaming = true;
			printk("Stream started\n");
		} else {
			if (!trigger_command(i2s_dev_rx, i2s_dev_tx, I2S_TRIGGER_DROP)) {
				continue;
			}
			streaming = false;
			printk("Stream stopped\n");
		}

		while (streaming && k_sem_take(&toggle_transfer, K_NO_WAIT) != 0) {
			void *rx_block = NULL;
			void *tx_block = NULL;
			size_t rx_size;
			int ret;

			/* Read RX (16 kHz) */
			ret = i2s_read(i2s_dev_rx, &rx_block, &rx_size);
			if (ret < 0) {
				printk("i2s_read failed: %d\n", ret);
				break;
			}

			/* Proccess rx data */
			process_block_data(rx_block, SAMPLES_PER_BLOCK_RX);

			/* Allocate TX block(32 kHz) */
			ret = k_mem_slab_alloc(&mem_slab_tx, &tx_block, K_NO_WAIT);
			if (ret < 0) {
				printk("Failed to allocate TX block: %d\n", ret);
				k_mem_slab_free(&mem_slab_rx, rx_block);
				break;
			}

			/* Upsample to 32kHz */
			audio_upsample_to_32k((const int16_t *)rx_block, (int32_t *)tx_block, 
			                      NUMBER_OF_CHANNELS, SAMPLE_FREQ_RX);

			k_mem_slab_free(&mem_slab_rx, rx_block);

			/* Send to TX (32 kHz) */
			ret = i2s_write(i2s_dev_tx, tx_block, BLOCK_SIZE_TX);
			if (ret < 0) {
				printk("i2s_write failed: %d\n", ret);
				k_mem_slab_free(&mem_slab_tx, tx_block);
				break;
			}
		}
	}
	return 0;
}