2012-01-26 36 views
7

Tôi bắt đầu viết một bộ tổng hợp mềm có đặc tính riêng: Bộ dao động sẽ có núm "dạng sóng liên tục" cho phép người dùng chọn hình sin, vuông và nhìn thấy những chiếc sóng răng liên tục. Đó là, nếu núm là tất cả các cách bên trái, đầu ra sẽ là một làn sóng sin, nếu nó ở giữa nó sẽ là một làn sóng răng cưa, nếu nó là tất cả các cách bên phải nó sẽ là một làn sóng vuông và sau đó các vị trí trung gian sẽ tạo ra các sóng là các phiên bản "nội suy" của các sóng cổ điển. - vị trí Knob và các loại sóng có thể thay đổi nhưng có một cách liên tục thay đổi hình thức sóng là mong muốn -Bộ tổng hợp âm thanh dạng sóng liên tục

Tôi đã nghĩ đến một vài cách để thực hiện các dao động:

  1. Hãy đến với một chức năng có vị trí núm và tính toán phổ của tín hiệu thực tế (một mảng biên độ và tần số) và sau đó sử dụng một loạt các hàm sin và một khối tổng để thực hiện tín hiệu đầu ra.

  2. Tương tự như 1. nhưng áp dụng một Fourier ngược chuyển đổi thay vì sin và sum (OK, vào thời điểm này tôi không chắc chắn nếu họ thực sự là những điều tương tự.)

  3. Tạo một bảng dạng sóng cho mỗi vị trí núm có thể và sử dụng kỹ thuật tổng hợp bảng sóng để tạo ra tín hiệu đầu ra.

  4. Bắt đầu với 2 sóng răng cưa (chúng chứa cả sóng hài đều và lẻ), đảo ngược một và tổng hợp chúng, đồng thời kiểm soát biên độ của từng nút bằng núm. Các hình thức sóng sẽ không

Tôi có một vài câu hỏi:

A. Tôi đã đọc rằng kỹ thuật số 1 là rất vi xử lý chuyên sâu và không thực sự khả thi. Điều này có đúng với các bộ xử lý ARM như bộ xử lý trên iPad không ??

B. Bất kỳ kỹ thuật nào tôi chọn đều có thể giải quyết vấn đề răng cưa đơn giản bằng cách kết nối bộ lọc low-pass với đầu ra của bộ dao động?

C. Bất kỳ đề xuất nào khác về cách triển khai bộ dao động như vậy?

D. Mọi đề xuất về bộ công cụ C++ nào để sử dụng? Tôi đã nhìn vào STK từ CCRMA nhưng tôi không biết nếu có các thư viện phù hợp hơn.

Chúc bạn may mắn! ;)

Chỉnh sửa: Ai đó đã chỉ cho tôi din đêm qua. Đường cong Bezier là một lựa chọn khác để xem xét.

+0

Bạn có muốn tạo mẫu của dạng sóng hoặc áp dụng mẫu đó cho tín hiệu khác không? Bạn đang xem xét một cách tiếp cận "nội suy" cụ thể? –

+0

Tôi muốn sử dụng điều này làm bộ tạo dao động âm thanh cho bộ tổng hợp. Sau đó tôi sẽ áp dụng lọc và có thể một số fx để làm cho âm thanh thú vị hơn. Các phương pháp tôi đã xem xét được mô tả trong 1 đến 4, không chắc chắn ý bạn là gì bởi "cách tiếp cận nội suy". –

+0

Whoa !! Cảm ơn tất cả mọi người đã trả lời, bây giờ tôi có một số bài tập về nhà :) Tôi sẽ bắt đầu dễ dàng lúc đầu: sử dụng dao động vuông, sin và răng cưa trong STK và chỉ đơn giản là mờ dần giữa ba âm thanh để xem âm thanh của nó như thế nào. Nếu tôi vẫn cần một cái gì đó phức tạp hơn, tôi sẽ khám phá những gợi ý khác được đưa ra. --- Tôi sẽ cho thêm một chút thời gian trước khi đánh dấu câu trả lời được chấp nhận --- –

Trả lời

5

Tôi không chắc bạn không làm quá phức tạp điều này. Nếu tôi hiểu chính xác, tất cả những gì bạn đang làm với núm dạng sóng liên tục của bạn có hiệu quả pha trộn với nhau một lượng khác nhau của 3 dạng sóng. Vì vậy, chỉ cần tạo ra tất cả 3 dạng sóng tất cả các thời gian, sau đó tổng hợp chúng cùng với lợi ích khác nhau theo sự pha trộn của dạng sóng bạn đã mô tả.

Để tổng hợp dạng sóng giới hạn băng tần để tránh răng cưa, có thể bạn sẽ tìm thấy hầu hết những gì bạn cần here.

Hy vọng điều đó sẽ hữu ích.

+0

Đây là những gì tôi đã làm, một crossfader đơn giản đã làm việc! :) –

1

Biến đổi Fourier là tuyến tính, do đó, lấy FFT, ví dụ: vuông và thấy sóng và crossfading mỗi hài hòa tuyến tính và sau đó đưa nó trở lại miền thời gian, hoặc bằng iFFT hoặc tổng hợp sin, nên cung cấp cho chính xác cùng một đầu ra như chỉ crossfading cưa và tín hiệu vuông trực tiếp. Tôi không chắc nếu đó là những gì bạn muốn làm, nhưng nếu nó không có cần phải làm FFTs hoặc tính toán các bảng trung gian. Có rất nhiều cách khác để "mờ dần" giữa các dạng sóng của khóa học - bạn có thể sử dụng biến dạng pha, ví dụ, với một đường cong biến dạng bao gồm các đoạn thẳng mà bạn di chuyển từ các vị trí tạo ra một hình vuông đến các vị trí tạo ra cái cưa. Điều này có lẽ rất khó thực hiện theo cách vốn có hạn chế.

Bí danh có thể, trên thực tế, thường được giải quyết bằng cách sử dụng lấy mẫu và lọc, hoặc chỉ lọc. Sử dụng các kỹ thuật hạn chế băng tần là tốt hơn vì bí danh sẽ luôn gây ra một số tiếng ồn, nhưng bạn thường có thể lọc nó đủ thấp để không nghe được, đó là những gì quan trọng cho tổng hợp âm thanh.

+0

+1 cho "Biến đổi bẩn là tuyến tính" –

2

Đây là câu trả lời cho B (Có thể giải quyết vấn đề răng cưa đơn giản bằng cách kết nối bộ lọc low-pass với đầu ra?) Chạm vào một số điểm khác.

Thật không may, câu trả lời là 'không'. Sự sai lệch là do sự có mặt của các tần số hài hòa trên tần số Nyquist (tức là một nửa tốc độ lấy mẫu.) Nếu các sóng hài đó có mặt trong dạng sóng dao động của bạn, việc lọc không thể giúp được. (Bộ lọc tích cực phù hợp sẽ tiêu diệt nhân vật của những con sóng mà bạn đã tạo ra.) Oversampling (một câu trả lời khác đề cập đến điều này) có thể, nhưng nó đắt tiền.

Để tránh điều này, bạn phải tạo dạng sóng 'dải giới hạn'. Đó là, dạng sóng không có sóng hài trên một số giá trị được chọn < Nyquist. Làm điều này là không tầm thường. Bài báo này here đáng để đọc. Có hai phương pháp thiết thực, được thiết lập để giải quyết vấn đề này: BLITs (Band Limited Impulse Train) và MinBLEPs. Cả hai phương pháp đều cố gắng làm mịn các gián đoạn tạo ra điều hòa bằng cách chèn 'vật liệu' vào các điểm thích hợp trong dạng sóng.

Với ý nghĩ đó, các tùy chọn của bạn bắt đầu co lại. Có lẽ thỏa hiệp tốt nhất giữa dễ dàng và âm thanh sẽ tạo ra một loạt các wavetables giới hạn của ban nhạc. Bạn vẫn cần phải điều tra một số hình thức chống răng cưa để xử lý các sóng nội suy.

ARM iDevice hoàn toàn có khả năng thực hiện DSP trong thời gian thực. Lời khuyên chung: viết mã chặt chẽ, sử dụng các hàm nội tuyến và tránh phân chia. Vòng lặp render của bạn sẽ được gọi là 44,100 lần một giây, do đó, miễn là mã của bạn hoàn thành trong vòng 1/44100 giây (0,023 mili giây), bạn sẽ không gặp vấn đề gì. Trong thực tế, bạn sẽ có thể chạy một số bộ dao động đồng thời mà không có vấn đề gì cả. Sự hiện diện của tất cả các ứng dụng âm nhạc trên cửa hàng ứng dụng là minh chứng cho điều đó.

STK là thư viện giới thiệu tuyệt vời. (Cuốn sách của Perry Cook "Tổng hợp âm thanh thời gian thực cho các ứng dụng tương tác" cũng là nền tảng tốt và đáng để đọc.) STK cố tình không được tối ưu hóa và tôi không chắc nó sẽ tạo ra các dạng sóng 'liên tục' của bạn như thế nào . kvraudio.commusicdsp.org phải nằm trong danh sách đọc của bạn.

+0

chỉ muốn thêm, với giải pháp 1. bộ lọc thông thấp trước khi tổng hợp sẽ thực sự hoạt động tốt, bởi vì bạn biết tần số của tất cả các bộ dao động trước khi bạn lấy mẫu, vì vậy bạn có thể bỏ qua các giai điệu có tần số cao hơn hơn tần số Nyquist. –

1

A. Tôi đã đọc kỹ thuật số 1 rất chuyên sâu về xử lý và không thực sự khả thi. Điều này có đúng với các bộ vi xử lý ARM như bộ xử lý trên iPad không?

Điều này làm phức tạp vấn đề đơn giản (chơi chữ có chủ ý). Accelerate.framework cung cấp các biến thể tối ưu hóa của các hàm này (fwiw), nhưng nó vẫn phức tạp hóa một vấn đề đơn giản. Như một lưu ý chung: các tính toán điểm động trên các thiết bị chậm. Việc triển khai điểm nổi có thể làm tổn hại đến chương trình của bạn một cách đáng kể.Nó có khả năng sẽ dẫn đến việc xâm phạm các tính năng, đa âm hoặc chất lượng một cách đáng kể. Mà không biết reqs, thật khó để nói liệu bạn có thể nhận được bằng với calcs điểm nổi.

B. Dù kỹ thuật nào tôi chọn, vấn đề răng cưa có thể được giải quyết đơn giản bằng cách kết nối bộ lọc low-pass với đầu ra của bộ dao động không?

Điều đó sẽ không hoạt động đối với các tín hiệu được tạo trong miền thời gian, trừ khi bạn bỏ qua.

C. Bất kỳ đề xuất nào khác về cách triển khai bộ dao động như vậy?

xem dưới đây

D. Bất kỳ đề xuất về mà C++ toolkit sử dụng không? Tôi đã nhìn vào STK từ CCRMA nhưng tôi không biết nếu có các thư viện phù hợp hơn.

STK giống như một công cụ hướng dẫn hơn là bộ công cụ được thiết kế cho trình tổng hợp được nhúng. Triển khai phù hợp hơn tồn tại.

Tùy chọn 1. Hãy đến với hàm có vị trí núm và tính phổ của tín hiệu thực tế (một dải biên độ và tần số) và sau đó sử dụng một loạt hàm sin và một khối tổng hợp để thực hiện tín hiệu đầu ra.

Lựa chọn 2. Tương tự như 1. nhưng áp dụng một Fourier ngược chuyển đổi thay vì sin và sum (OK, vào thời điểm này tôi không chắc chắn nếu họ thực sự là những điều tương tự.)

Đó là tương đối chậm trên máy tính để bàn.

Tùy chọn 4. Bắt đầu với 2 sóng răng cưa (chúng chứa cả sóng hài và cả lẻ), đảo ngược một và tổng hợp chúng, và điều khiển biên độ của từng nút bằng núm. Các dạng sóng sẽ không là

Bạn có thể thực hiện điều này khá hiệu quả (ví dụ: với BLIT) để tạo bí danh miễn phí. Tuy nhiên, BLIT đã hạn chế một số dạng sóng (bạn có thể sử dụng nó cho Saw và Square). Bạn có thể nhìn lại lịch sử và hỏi "Làm cách nào họ giải quyết vấn đề này trong phần cứng và phần mềm synths ca. 2000". Đây là một giải pháp. Một số khác là:

Tùy chọn 3. Tạo bảng dạng sóng cho từng vị trí núm có thể và sử dụng kỹ thuật tổng hợp bảng sóng để tạo tín hiệu đầu ra.

Xem xét khả năng của thiết bị, tôi khuyên bạn nên triển khai tính năng này hoặc BLIT.

Bảng dễ bị lúng túng và triển khai, đồng thời cung cấp kết quả âm thanh và CPU tốt. Nó cũng có khả năng cấu hình cao cho việc cân bằng chất lượng CPU/bộ nhớ/chất lượng.

Nếu bạn muốn bí danh miễn phí (hoặc đóng), hãy truy cập BLIT (hoặc họ hàng). Lý do là bạn sẽ cần một bộ nhớ tốt và một số lượng tốt oversampling cho tối thiểu để không có răng cưa âm thanh với wavetables.

Triển khai:

Có rất nhiều BLIT (và gia đình) triển khai trực tuyến.

Dưới đây là một khăn ăn-scribbling cho các bảng:

enum { WF_Sine, WF_Saw, WF_Square, WF_COUNT }; 
enum { TableSize = SomePowerOfTwo }; 

struct sc_waveform { 
    uint32_t at[TableSize]; 
}; 

enum { NPitches = Something }; 

sc_waveform oscs[WF_COUNT][NPitches]; 

Sau khi khởi tạo, sử dụng phụ gia tổng hợp để cư oscs.

Trong khi phát lại, sử dụng một trong hai:

  • suy và oversampling để đọc từ các bảng
  • hoặc một số lượng tốt của oversampling của tín hiệu và sau đó downsampling (đó là CPU hiệu quả).

Để tham khảo: Tôi muốn ước tính nội suy tuyến tính của một bảng mà tiêu thụ một số lượng vô trách nhiệm của bộ nhớ (xem xét số tiền có sẵn) mà không oversampling nên giữ tần số bí danh của bạn bằng hoặc thấp hơn -40 dB nếu bạn đã không để giảm âm thanh các partials cao nhất và bạn kết xuất ở 44,1kHz. Đây là một cách tiếp cận bạo lực ngây thơ! Bạn có thể làm tốt hơn với một chút công việc phụ.

Cuối cùng, bạn cũng nên tìm thông tin có liên quan nếu bạn google "Vector Synthesis" - những gì bạn mô tả là một dạng nguyên thủy của nó.

+0

+1 Đây là một câu trả lời rất minh họa, tôi đã học được rất nhiều từ nó. –

Các vấn đề liên quan