forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Speaker Support BasedHardware#567 (BasedHardware#686)
BasedHardware#567 This is a rebase of the previous PR. How to test: In the firmware_v1.0 file, Flash the zephyr.uf2 file in the file "build_speaker". -Then use the script "discover_devices.py" to find the device id of your Omi device. This is to avoid cases where there are multiple friends connected at once. If there is more than one friend then just test all of them. In the script play_sound_on_friend.py, (in firmware_v1.0) On line 20 add the device id of your friend. This is to avoid cases where there is more than one friend nearby. On line 21 add your Deepgram API key. Then save and run the script by typing a small string. For example, one line could be python3 play_sound_on_friend.py "hello" Which should get the speaker to say hello. Make sure your device is connected by USB or you have connected a 3.3V pin to the speaker. BasedHardware#573 (For now it is disabled but since this uses very similar code). A sound should play automatically when you compile and run the zephyr.uf2 file. Of course this file can be modified to play any haptic sound provided you enter the appropriate lookup table.
- Loading branch information
Showing
8 changed files
with
350 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/sys/printk.h> | ||
#include <zephyr/device.h> | ||
|
||
#include <zephyr/drivers/pwm.h> | ||
#include <zephyr/drivers/i2s.h> | ||
#include <zephyr/drivers/gpio.h> | ||
|
||
#include <string.h> | ||
#include <zephyr/logging/log.h> | ||
#include <zephyr/logging/log_ctrl.h> | ||
|
||
LOG_MODULE_REGISTER(speaker, CONFIG_LOG_DEFAULT_LEVEL); | ||
|
||
#define MAX_BLOCK_SIZE 25000 //24000 * 2 | ||
#define BLOCK_COUNT 2 | ||
#define SAMPLE_FREQUENCY 8000 | ||
#define NUMBER_OF_CHANNELS 2 | ||
#define PACKET_SIZE 400 | ||
#define WORD_SIZE 16 | ||
K_MEM_SLAB_DEFINE_STATIC(mem_slab, MAX_BLOCK_SIZE, BLOCK_COUNT, 4); | ||
static void* rx_buffer; | ||
static void* buzz_buffer; | ||
static int16_t *ptr2; | ||
static int16_t *clear_ptr; | ||
static struct device *speaker; | ||
static uint16_t current_length; | ||
static uint16_t offset; | ||
int speaker_init() { | ||
const struct device *mic = device_get_binding("I2S_0"); | ||
speaker = mic; | ||
if (!device_is_ready(mic)) { | ||
LOG_ERR("Speaker device is not supported : %s", mic->name); | ||
return 0; | ||
} | ||
struct i2s_config config = { | ||
.word_size= WORD_SIZE, //how long is one left/right word. | ||
.channels = NUMBER_OF_CHANNELS, //how many words in a frame 2 | ||
.format = I2S_FMT_DATA_FORMAT_LEFT_JUSTIFIED, //format | ||
// .format = I2S_FMT_DATA_FORMAT_I2S, | ||
.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER | I2S_OPT_BIT_CLK_GATED, //how to configure the mclock | ||
.frame_clk_freq = SAMPLE_FREQUENCY, /* Sampling rate */ | ||
.mem_slab = &mem_slab,/* Memory slab to store rx/tx data */ | ||
.block_size = MAX_BLOCK_SIZE,/* size of ONE memory block in bytes */ | ||
.timeout = -1, /* Number of milliseconds to wait in case Tx queue is full or RX queue is empty, or 0, or SYS_FOREVER_MS */ | ||
}; | ||
int err = i2s_configure(mic, I2S_DIR_TX, &config); | ||
if (err < 0) { | ||
LOG_INF("Failed to configure Microphone (%d)", err); | ||
return 0; | ||
} | ||
err = k_mem_slab_alloc(&mem_slab, &rx_buffer, K_MSEC(200)); | ||
if (err) { | ||
LOG_INF("Failed to allocate memory again(%d)", err); | ||
return 0; | ||
} | ||
|
||
err = k_mem_slab_alloc(&mem_slab, &buzz_buffer, K_MSEC(200)); | ||
if (err) { | ||
LOG_INF("Failed to allocate memory again(%d)", err); | ||
return 0; | ||
} | ||
|
||
memset(rx_buffer, 0, MAX_BLOCK_SIZE); | ||
int16_t *noise = (int16_t*)buzz_buffer; | ||
|
||
memset(buzz_buffer, 0, MAX_BLOCK_SIZE); | ||
return 1; | ||
} | ||
|
||
uint16_t speak(uint16_t len, const void *buf) { | ||
|
||
uint16_t amount = 0; | ||
amount = len; | ||
if (len == 4) //if stage 1 | ||
{ | ||
current_length = ((uint32_t *)buf)[0]; | ||
LOG_INF("About to write %u bytes", current_length); | ||
ptr2 = (int16_t *)rx_buffer; | ||
clear_ptr = (int16_t *)rx_buffer; | ||
} | ||
else { //if not stage 1 | ||
if (current_length > PACKET_SIZE) { | ||
LOG_INF("Data length: %u", len); | ||
current_length = current_length - PACKET_SIZE; | ||
LOG_INF("remaining data: %u", current_length); | ||
|
||
for (int i = 0; i < len/2; i++) { | ||
*ptr2++ = ((int16_t *)buf)[i]; | ||
ptr2++; | ||
|
||
} | ||
offset = offset + len; | ||
} | ||
else if (current_length < PACKET_SIZE) { | ||
LOG_INF("entered the final stretch"); | ||
LOG_INF("Data length: %u", len); | ||
current_length = current_length - len; | ||
LOG_INF("remaining data: %u", current_length); | ||
// memcpy(rx_buffer+offset, buf, len); | ||
for (int i = 0; i < len/2; i++) { | ||
*ptr2++ = ((int16_t *)buf)[i]; | ||
ptr2++; | ||
} | ||
offset = offset + len; | ||
LOG_INF("offset: %u", offset); | ||
|
||
|
||
i2s_write(speaker, rx_buffer, MAX_BLOCK_SIZE); | ||
i2s_trigger(speaker, I2S_DIR_TX, I2S_TRIGGER_START);// calls are probably non blocking | ||
i2s_trigger(speaker, I2S_DIR_TX, I2S_TRIGGER_DRAIN); | ||
|
||
//clear the buffer | ||
|
||
k_sleep(K_MSEC(4000)); | ||
memset(clear_ptr, 0, MAX_BLOCK_SIZE); | ||
} | ||
|
||
} | ||
return amount; | ||
} | ||
|
||
|
||
void buzz() { | ||
i2s_write(speaker, buzz_buffer, MAX_BLOCK_SIZE); | ||
i2s_trigger(speaker, I2S_DIR_TX, I2S_TRIGGER_START);// calls are probably non blocking | ||
i2s_trigger(speaker, I2S_DIR_TX, I2S_TRIGGER_DRAIN); | ||
k_msleep(4000); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#pragma once | ||
#include <zephyr/kernel.h> | ||
int speaker_init(); | ||
uint16_t speak(); | ||
void buzz(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import asyncio | ||
from bleak import BleakScanner | ||
|
||
async def main(): | ||
devices = await BleakScanner.discover() | ||
for d in devices: | ||
print(d) | ||
|
||
asyncio.run(main()) |
Oops, something went wrong.