paint-brush
Lớp đệm FIFO của Python cho âm thanh - một thuật toántừ tác giả@giwyni
387 lượt đọc
387 lượt đọc

Lớp đệm FIFO của Python cho âm thanh - một thuật toán

từ tác giả GIWYNI5m2024/06/27
Read on Terminal Reader

dài quá đọc không nổi

Bộ đệm FIFO là cấu trúc dữ liệu thường cần thiết cho nhiều trường hợp sử dụng. Các mục được đưa vào bộ đệm và được truy xuất theo thứ tự chúng được đưa vào ngoại trừ việc chúng được truy xuất với số lượng tùy ý. Bài viết này mô tả một thuật toán cho bộ đệm này.
featured image - Lớp đệm FIFO của Python cho âm thanh - một thuật toán
GIWYNI HackerNoon profile picture
0-item
1-item
2-item

Bộ đệm FIFO là cấu trúc dữ liệu thường cần thiết cho nhiều trường hợp sử dụng. Các mục được đưa vào bộ đệm và được truy xuất theo thứ tự chúng được đưa vào. Đây là chức năng tương tự như Hàng đợi. Sự khác biệt giữa Hàng đợi và Bộ đệm là trong bộ đệm, dữ liệu được chèn đều có cùng loại dữ liệu. Hơn nữa, một lượng dữ liệu tùy ý có thể được chèn vào và lượng truy xuất cũng tùy ý.


Các trường hợp sử dụng mà bạn muốn đặt và truy xuất các mục số tùy ý cùng loại là gì? Chuyển hướng sang các lĩnh vực khác ngoài xử lý dữ liệu: Hãy nghĩ đến tài khoản ngân hàng: Tiền được đưa vào với số lượng khác nhau và lấy ra với số lượng khác nhau khi cần thiết..Điều tương tự cũng áp dụng cho việc lưu trữ ngũ cốc trong trang trại..Nhưng các ngân hàng và kho thóc lại làm những việc này. Những gì còn lại cho chúng ta trong lĩnh vực CNTT là Dữ liệu âm thanh, dữ liệu này đến rất nhanh nhưng phải khởi hành ở tốc độ cụ thể chậm hơn để có thể nghe được. Thủ phạm ngày nay của điều này là các công cụ Chuyển văn bản thành giọng nói tạo điều kiện thuận lợi cho giao tiếp giữa người và máy tương tác. Máy nhận văn bản (có thể từ công cụ AI) mà nó chuyển đổi thành byte âm thanh để gửi đến con người ở tốc độ cụ thể mà con người có thể nghe thấy. Đúng như mong đợi, máy tạo ra các byte âm thanh với tốc độ nhanh, sau đó phải được đệm vào bộ đệm để có thể truyền đến con người ở tốc độ chậm hơn nhiều. Một sự tương tự là trạm xăng địa phương của bạn. Text to speech là chiếc xe chở xăng bơm rất nhiều xăng với tốc độ nhanh, đổ đầy các bình xăng trong lòng cây xăng. Sau đó, những thứ này sẽ được chuyển đến xe ô tô của khách hàng hoặc các phương tiện khác với tốc độ chậm hơn nhiều.


Tóm lại, việc chuyển đổi văn bản thành giọng nói (âm thanh) có thể diễn ra nhanh hơn nhiều. Cần có Bộ đệm âm thanh để nhận âm thanh từ văn bản thành giọng nói (tts) để lấp đầy bộ đệm. Bộ đệm này sau đó được rút cạn theo tốc độ lời nói của con người và con người có thể hiểu được.


Dữ liệu âm thanh: Dữ liệu bao gồm một chuỗi các số biểu thị các giá trị của tín hiệu âm thanh theo các khoảng thời gian đều đặn (gọi là tốc độ lấy mẫu). Ngoài ra còn có khái niệm về kênh, tức là nhiều tín hiệu âm thanh, dẫn đến một chuỗi có nhiều giá trị.


Với mục đích của bài viết này, chúng tôi sẽ chỉ xem xét một kênh ở phía đầu vào và một kênh ở phía đầu ra.


Numpy: Đây là phần mềm tạo điều kiện thuận lợi cho việc lưu trữ/truy xuất các mảng số được tối ưu hóa về hiệu suất.

Thiết kế:

Yêu cầu là: có thể nhập số lượng khung dữ liệu âm thanh tùy ý (khung là số đại diện cho điểm dữ liệu âm thanh), là một mảng các giá trị tín hiệu âm thanh được sắp xếp theo thứ tự. Về phía đầu ra, có thể truy xuất số lượng khung hình này tùy ý. Tất nhiên, chúng tôi phải thêm các tính năng tiện lợi để xử lý các hạn chế, đó là kích thước bộ đệm hạn chế (gây ra tình trạng đầy bộ đệm ở đầu vào), không có sẵn dữ liệu âm thanh (bộ đệm trống ở phía đầu ra). Các tính năng tiện lợi khác sẽ bao gồm việc không điền dữ liệu âm thanh, trong trường hợp nhiều dữ liệu âm thanh được yêu cầu hơn mức có sẵn khi truy xuất bộ đệm.

Thực hiện:

Phần sau đây mô tả cách triển khai bộ đệm như vậy trong Python:


Các byte âm thanh đến được lưu trữ trong Bộ đệm. Bộ đệm có một con trỏ 'dưới cùng', con trỏ này chỉ ra mức độ mà bộ đệm được lấp đầy. Nó cũng có một 'con trỏ bắt đầu' là điểm bắt đầu của bộ đệm nơi dữ liệu mới có thể được đẩy. Con trỏ bắt đầu được cố định ở đầu bộ đệm. Con trỏ dưới cùng là 'động' và 'lên xuống': lên khi dữ liệu được trích xuất và 'xuống' khi dữ liệu được chèn vào. Dữ liệu luôn được chèn ở trên cùng (con trỏ bắt đầu) của bộ đệm dẫn đến dữ liệu hiện có trong bộ đệm bị đẩy 'xuống' do đó làm tăng giá trị của con trỏ dưới cùng.


Tình trạng trống bộ đệm xảy ra khi con trỏ dưới cùng bằng con trỏ bắt đầu. Tình trạng đầy bộ đệm xảy ra khi con trỏ dưới cùng bằng độ dài của bộ đệm.


Chúng ta cũng có thể bao gồm 'sự thất bại duyên dáng' để xử lý các điều kiện khi bộ đệm đầy.


Khi bộ đệm đầy và dữ liệu cần được chèn vào, hãy đưa ra Ngoại lệ. Khi bộ đệm trống (bao gồm cả trường hợp dữ liệu được yêu cầu nhiều hơn mức có sẵn trong bộ đệm) trả về 'số 0' cho dữ liệu bị thiếu. Đây là âm thanh tương đương với 'im lặng' khi không có lời nào được nói ra.


Sơ đồ của bộ đệm này là:


Mã hóa: (Tuyên bố từ chối trách nhiệm: Không có AI nào được sử dụng để tạo mã bên dưới. Mọi lời đổ lỗi (tốt hơn là khen ngợi) sẽ được giao cho Tác giả..)


Tuân theo nguyên tắc Hướng đối tượng, mã được viết dưới dạng lớp/đối tượng và rất dễ sử dụng. Toàn bộ mã là:


 import numpy as np #numpy is the standard package or numerical array processing class AudioBuf: def __init__(self,bufSize:int,name:str='',dtype=np.int16): self.buffer = np.zeros((bufSize), dtype=dtype) self.bufSize=bufSize self.dtype=dtype self.idx=0 self.name=name #give a name to the buffer. def putInBuf(self,inData:np.ndarray[np.dtype[np.int16]]): inData=inData[:, 0] #Get the 1st col = channel 0 - mono remainder = self.bufSize - self.idx #space available for insertion if remainder < len(inData): msg=f'Error: Buffer {self.name} is full' print(msg) self.showBuf() raise ValueError(msg) self.buffer[self.idx:self.idx + len(inData)] = inData self.idx += len(inData) def getFromBuf(self,outDataLen:int = None)->np.ndarray: if not outDataLen: outDataLen=self.idx # return entire data of length is not specified if self.idx >= outDataLen: retVal = self.buffer[:outDataLen] self.buffer[0:self.idx-outDataLen]=self.buffer[outDataLen:self.idx] #move buffer up self.idx -= outDataLen else: retVal=np.zeros((outDataLen), dtype=self.dtype) retVal[0:self.idx] = self.buffer[0:self.idx] self.idx=0 return np.reshape(retVal,(-1,1)) #The -1 value automatically calculates to the number of elements def showBuf(self): print(f'AudioBuf : {self.name} has length= {self.idx} with capacity {self.bufSize}')

Phần kết luận:

Bộ đệm âm thanh là điều cần thiết và quan trọng hơn hiện nay do có nhiều ứng dụng xử lý âm thanh. Thuật toán đệm âm thanh được trình bày ở trên là một lớp python tiện lợi.