Project này cho thấy cách tạo âm thanh và video tổng hợp ở các kỹ thuật và tốc độ lấy mẫu khác nhau bằng cách sử dụng DAC tích hợp của ESP32.

Đấu dây

Việc nối dây khá đơn giản. Video được kết nối với gpio 25 và âm thanh đến 26. Nên sử dụng tụ điện 10µF để loại bỏ phần bù DC.

Chức năng

Video đang chạy trên 13,33 triệu mẫu trên I2S. Tốc độ lấy mẫu này chỉ có thể đạt được bằng chế độ kênh đơn của I2S. Để có thể sử dụng DAC thứ hai, mình có thể sử dụng chế độ đặc biệt “ẩn” cho phép I2S FIFO ghi một giá trị không đổi vào DAC thứ hai (Bảng 57 trang 293 của bảng dữ liệu ) . Giá trị không đổi có thể được thay đổi bất cứ lúc nào từ mã. Bằng cách này, mình có thể thiết lập chức năng hẹn giờ theo tốc độ mẫu âm thanh mong muốn và ghi các mẫu. Tốc độ lấy mẫu của âm thanh thấp hơn nhiều so với tốc độ lấy mẫu của video. Việc ghi trực tiếp vào thanh ghi của DAC thứ hai không hoạt động vì nó luôn bị I2S FIFO ghi đè.

Mã số

Mã được viết bằng C++ và chạy trong Arduino IDE. Cần tích hợp Arduino ESP32 để biên dịch mã (Vui lòng làm theo hướng dẫn tại đây:  https://github.com/espressif/arduino-esp32 ).

Cách dễ nhất để bắt đầu là thử mã ví dụ. AudioVideoExample.ino  có một số nhận xét về cái gì làm cái gì.
https://github.com/bitluni/AudioVideoExample
Bạn chỉ cần sao chép ví dụ về điểm bắt đầu của Project và thêm từng chút một đã thay đổi.

Dưới đây là một số điều cần thiết:

Chế độ FIFO để có thể sử dụng giá trị không đổi cho DAC thứ hai được đặt bằng cách sử dụng các dòng này trong CompositeOutput.h :// tháo DAC SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD_V, 3, I2S_TX_CHAN_MOD_S); SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD_V, 1, I2S_TX_FIFO_MOD_S);

Các mẫu âm thanh được ghi từ chức năng hẹn giờ (AudioOutput.h)void IRAM_ATTR hẹn giờInterrupt(Đầu ra âm thanh *đầu ra âm thanh) { uint32_t intStatus = TIMERG0. int_st_timers.val ; if(intStatus & BIT(TIMER_0)) { TIMERG0.hw_timer[TIMER_0].update = 1; TIMERG0. int_clr_timers.t0 = 1; TIMERG0.hw_timer[TIMER_0].config.alarm_en = 1; WRITE_PERI_REG(I2S_CONF_SIGLE_DATA_REG(0), audioOutput->audioSystem->nextSample() << 24); } }

Bộ hẹn giờ được khởi tạo trong hàm tạo của lớp AudioOutput.

lớp AudioSystem xử lý bộ đệm âm thanh và trộn tất cả các âm thanh hiện đang phát.

Các tệp tiêu đề do các biên tập viên bên dưới tạo ra được bao gồm như thế này (các tệp được lưu trữ trong thư mục con gfx/sfx của Project):#include “gfx/sprites.h” #include “sfx/sounds.h”

Trong quá trình thiết lập ví dụ, âm nhạc được bắt đầu theo vòng lặp. Âm nhạc nằm ở chỉ số 0 của bảng sóng, biên độ 1 và tốc độ phát lại 1 được sử dụng. Tham số cuối cùng là kích hoạt vòng lặp.// Phát âm thanh đầu tiên trong vòng lặp (âm nhạc) sound.play(audioSystem , 0, 1, 1, true);

Việc phát một âm thanh sử dụng biên độ và tốc độ mặc định có thể được thực hiện như thế nàyâm thanh.play(audioSystem , 1);

Tham số trả về của phương thức phát trả về một id có thể được sử dụng để dừng phát lại âm thanhint play(Hệ thống âm thanh &Hệ thống âm thanh, int soundNumber, biên độ float = 1, tốc độ float = 1, vòng lặp bool = false)void stop(Hệ thống âm thanh &Hệ thống âm thanh, int id)

Tất cả âm thanh được phát bởi một bảng sóng cụ thể có thể được dừng bằng cách sử dụngvoid stop(Hệ thống âm thanh &Hệ thống âm thanh)

Bằng cách này, nếu âm nhạc được nhóm thành một vòng lặp có thể sóng riêng biệt thì nhạc có thể bị dừng các lúc nào mà không cần xử lý các id trước đó được trả về khi phát.

Các họa tiết được vẽ bằng hàmvoid draw(Đồ họa &g, int sprite, int x, int y)

sprite là chỉ số của sprite được vẽ. Nguồn gốc của sprite sẽ được đặt thành x, y. Điểm gốc được xác định bởi điểm đầu tiên của sprite có thể được đặt trong trình chỉnh sửa (xem bên dưới). Điểm bổ sung có thể được sử dụng làm hộp nhấn, v.v. Chúng có thể được đọc bằng cách sử dụngconst short *point(int sprite, int point)

Độ phân giải có thể được xác định bằng cách sử dụngint xres(int sprite) int yres(int sprite)

Nếu bạn muốn thử một Project thú vị, hãy xem
https://github.com/bitluni/TetrisSpaceX.
Phần này cho thấy cách bạn có thể triển khai một trò chơi… mặc dù nó có thể cần tái cấu trúc một lần nữa.

Bạn có thể tìm thấy mã dành cho trình chỉnh sửa tại đây nhưng bạn cũng có thể sử dụng trình chỉnh sửa được nhúng bên dưới
https://github.com/bitluni/WavetableEditor
https://github.com/bitluni/SpriteEditor

Trình chỉnh sửa bảng sóng

Trình chỉnh sửa wavetable có khả năng lưu trữ và khôi phục các Project phức tạp dưới dạng tệp .json. Bằng cách này, bạn có thể sửa đổi bảng sóng của mình sau này. Không thể tải lại .h đã xuất vì tệp âm thanh gốc bị mất trong quá trình này. Khi lưu trữ liên kết .json và .ha được hiển thị, bạn phải nhấp vào để lưu trữ tệp. Khi xuất .h cũng có tệp .txt được cung cấp các chỉ mục và tên tệp để bạn tham khảo.

? : mở Project được lưu trữ dưới dạng tệp .json
? : lưu trữ Project dưới dạng tệp .json
? : thêm tệp âm thanh
.h : xuất dưới dạng tên tệp tiêu đề
: Đây là tên của các tệp và bảng sóng trong mã sẽ có (chỉ sử dụng các ký tự hợp lệ cho tên biến)
normalize : các tệp âm thanh sẽ được điều chỉnh đến âm lượng tối đa khi xuất
tỷ lệ lấy mẫu : đây là tỷ lệ lấy mẫu cho xuất khẩu. Tỷ lệ cao hơn sẽ chiếm nhiều không gian hơn. (44100 là chất lượng CD)

(nếu bạn cần thêm dung lượng, hãy sử dụng liên kết này )

https://bitluni.net/wp-content/uploads/2018/03/WavetableEditor.html

Trình chỉnh sửa Sprite

Giống như trình soạn thảo có thể điều chỉnh được, trình chỉnh sửa sprite có khả năng lưu trữ và khôi phục các Project phức tạp dưới dạng tệp .json. Bằng cách này, bạn có thể sửa đổi bộ sưu tập sprite của mình sau này. Không thể tải lại .h đã xuất vì các tệp đồ họa gốc bị mất trong quá trình này. Khi lưu trữ liên kết .json và .ha được hiển thị, bạn phải nhấp vào để lưu trữ tệp. Khi xuất .h cũng có tệp .txt được cung cấp các chỉ mục và tên tệp để bạn tham khảo.
Sử dụng chuột để thêm điểm vào một sprite. Điểm đầu tiên được sử dụng làm gốc của sprite (nếu không đặt thì góc trên bên trái sẽ được sử dụng).. Các điểm khác có thể được sử dụng tùy ý.

TRUNG TÂM SỬA CHỮA ĐIỆN TỬ QUẢNG BÌNH
MR. XÔ - 0901.679.359 - 80 Võ Thị Sáu, Phường Quảng Thuận, tx Ba Đồn, tỉnh Quảng Bình
Sửa điện tử tại Quảng Bình

? : mở Project được lưu trữ dưới dạng tệp .json
? : lưu trữ Project dưới dạng tệp .json
? : thêm tệp đồ họa
.h : xuất dưới dạng tên tệp tiêu đề
: Đây là tên mà các tệp và sprite trong mã sẽ có (chỉ sử dụng các ký tự hợp lệ cho tên biến)
giá trị xám tối đa : giá trị xám tối đa có thể được sử dụng (lên đến 255)
độ trong suốt : đây là giá trị byte được sử dụng để lưu trữ độ trong suốt. (sử dụng giá trị nào đó cao hơn giá trị màu xám tối đa của bạn)
? : phóng to các họa tiết để đặt điểm dễ dàng hơn
⌗ : cắt xén. tất cả các họa tiết sẽ được giảm xuống phần không trong suốt. điểm sẽ được điều chỉnh. Sử dụng cẩn thận.. không có hoàn tác. mình sử dụng nó sau khi lưu vào .json và trước khi xuất sang .h để đảm bảo an toàn cho một số dung lượng.

(nếu bạn cần thêm dung lượng, hãy sử dụng liên kết này )

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

1 + 5 =