17

Là một phần của một dự án nghiên cứu tại nhà, tôi đang cố gắng tìm cách giảm/chuyển đổi bài hát thành tiếng ồn giống như tín hiệu âm thanh (giai điệu cơ bản mà con người chúng ta cảm nhận khi chúng ta nghe một bài hát). Trước khi tôi tiến hành thêm nữa trong việc mô tả nỗ lực của mình về vấn đề này, tôi muốn đề cập đến rằng tôi hoàn toàn mới đối với phân tích âm thanh mặc dù tôi có nhiều kinh nghiệm về phân tích hình ảnh và video.Làm thế nào để chuyển đổi một ca khúc sân từ một thuật toán khai thác giai điệu để một tiếng ồn như tín hiệu âm thanh

Sau khi googling một chút, tôi đã tìm thấy một loạt các thuật toán trích xuất giai điệu. Với một tín hiệu âm thanh đa âm của một bài hát (ví dụ: .wav file), chúng xuất ra một nốt nhạc --- tại mỗi thời điểm, chúng ước tính sân trội (đến từ giọng ca sĩ hoặc một số công cụ tạo giai điệu) và theo dõi ưu thế quảng cáo chiêu hàng theo thời gian.

Tôi đã đọc một vài bài báo và dường như họ tính toán một thời gian ngắn biến đổi Fourier của bài hát, và sau đó thực hiện một số phân tích về quang phổ để nhận và theo dõi sân chính. Khai thác giai điệu chỉ là một thành phần trong hệ thống mà tôi đang cố gắng phát triển, vì vậy tôi không ngại sử dụng bất kỳ thuật toán nào có sẵn cho đến khi thực hiện một công việc tốt trên các tệp âm thanh của tôi và mã có sẵn. Vì tôi mới làm quen với điều này, tôi rất sẵn lòng nghe bất kỳ đề xuất nào về thuật toán nào được biết là hoạt động tốt và tôi có thể tìm mã của nó ở đâu.

tôi thấy hai thuật toán:

  1. Yaapt pitch tracking
  2. Melodia

tôi đã chọn Melodia như kết quả trên các thể loại âm nhạc khác nhau trông khá ấn tượng. Vui lòng kiểm tra this to see its results. Sự ồn ào mà bạn nghe được đối với từng phần âm nhạc về cơ bản là những gì tôi quan tâm.

"Đây là thế hệ hài hước cho bất kỳ bài hát tùy ý nào mà tôi muốn bạn giúp đỡ trong câu hỏi này".

Thuật toán (có sẵn dưới dạng plugin vamp) xuất ra bản nhạc quảng cáo --- [time_stamp, pitch/frequency] --- ma trận Nx2 trong cột đầu tiên là dấu thời gian (tính bằng giây) và giây cột là mốc chính được phát hiện tại dấu thời gian tương ứng. Hiển thị dưới đây là hình ảnh của ca khúc được lấy từ thuật toán được phủ màu tím với tín hiệu miền thời gian của bài hát (ở trên) và nó phổ/ngắn-thời gian. Giá trị âm của quảng cáo chiêu hàng/tần suất thể hiện ước tính mức độ chi phối của thuật toán cho các phân đoạn không được lồng tiếng/không chuyển động. Vì vậy, tất cả các ước tính sân> = 0 tương ứng với giai điệu, phần còn lại không quan trọng đối với tôi.

Pitch-track overlay with a song's waveform and spectrogram

Bây giờ tôi muốn chuyển đổi theo dõi sân này trở lại một ồn ào như tín hiệu âm thanh - giống như các tác giả có nó trên trang web của họ.

Dưới đây là một hàm MATLAB mà tôi đã viết để làm điều này:

function [melSignal] = melody2audio(melody, varargin) 
% melSignal = melody2audio(melody, Fs, synthtype) 
% melSignal = melody2audio(melody, Fs) 
% melSignal = melody2audio(melody) 
% 
% Convert melody/pitch-track to a time-domain signal 
% 
% Inputs: 
% 
%  melody - [time-stamp, dominant-frequency] 
%   an Nx2 matrix with time-stamp in the 
%   first column and the detected dominant 
%   frequency at corresponding time-stamp 
%   in the second column. 
% 
%  synthtype - string to choose synthesis method 
%  passed to synth function in synth.m 
%  current choices are: 'fm', 'sine' or 'saw' 
%  default='fm' 
% 
%  Fs - sampling frequency in Hz 
%  default = 44.1e3 
% 
% Output: 
% 
%  melSignal -- time-domain representation of the 
%     melody. When you play this, you 
%     are supposed to hear a humming 
%     of the input melody/pitch-track 
% 

    p = inputParser; 
    p.addRequired('melody', @isnumeric); 
    p.addParamValue('Fs', 44100, @(x) isnumeric(x) && isscalar(x)); 
    p.addParamValue('synthtype', 'fm', @(x) ismember(x, {'fm', 'sine', 'saw'})); 
    p.addParamValue('amp', 60/127, @(x) isnumeric(x) && isscalar(x)); 
    p.parse(melody, varargin{:}); 

    parameters = p.Results; 

    % get parameter values 
    Fs = parameters.Fs; 
    synthtype = parameters.synthtype; 
    amp = parameters.amp; 

    % generate melody 
    numTimePoints = size(melody,1); 
    endtime = melody(end,1); 
    melSignal = zeros(1, ceil(endtime*Fs)); 

    h = waitbar(0, 'Generating Melody Audio'); 

    for i = 1:numTimePoints 

     % frequency 
     freq = max(0, melody(i,2)); 

     % duration 
     if i > 1 
      n1 = floor(melody(i-1,1)*Fs)+1; 
      dur = melody(i,1) - melody(i-1,1); 
     else 
      n1 = 1; 
      dur = melody(i,1);    
     end 

     % synthesize/generate signal of given freq 
     sig = synth(freq, dur, amp, Fs, synthtype); 

     N = length(sig); 

     % augment note to whole signal 
     melSignal(n1:n1+N-1) = melSignal(n1:n1+N-1) + reshape(sig,1,[]); 

     % update status 
     waitbar(i/size(melody,1)); 

    end 

    close(h); 

end 

Logic cơ bản đằng sau mã này là như sau: tại mỗi thời gian tem, tôi tổng hợp một làn sóng ngắn ngủi (nói một sin -wave) với tần số bằng tần số/tần số chi phối được phát hiện tại thời điểm đó trong một khoảng thời gian bằng khoảng trống của nó với dấu thời gian tiếp theo trong ma trận giai điệu đầu vào. Tôi chỉ tự hỏi liệu tôi có làm đúng không.

Sau đó, tôi lấy tín hiệu âm thanh tôi nhận được từ chức năng này và phát nó bằng bài hát gốc (giai điệu trên kênh bên trái và bài hát gốc trên kênh bên phải).Mặc dù tín hiệu âm thanh được tạo ra dường như phân đoạn các nguồn tạo giai điệu (voice/lead-intstrument) khá tốt - hoạt động của nó ở đó giọng nói và không ở mọi nơi khác --- bản thân tín hiệu không còn ồn ào nữa. beep beep beeeeep beep beeep beeeeeeeep) mà các tác giả hiển thị trên trang web của họ. Cụ thể, dưới đây là hình ảnh hiển thị tín hiệu miền thời gian của bài hát đầu vào ở dưới cùng và tín hiệu miền thời gian của giai điệu được tạo bằng chức năng của tôi.

enter image description here

Một vấn đề chính là - mặc dù tôi đang cho tần số của sóng để tạo ra tại mỗi thời gian tem và cũng là thời gian, tôi không biết làm thế nào để thiết lập biên độ của sóng. Bây giờ, tôi đặt biên độ là giá trị bằng phẳng/không đổi và tôi nghi ngờ đây là vấn đề.

Có ai có bất kỳ đề xuất nào về điều này không? Tôi hoan nghênh các đề xuất trong bất kỳ ngôn ngữ chương trình nào (tốt nhất là MATLAB, python, C++), nhưng tôi đoán câu hỏi của tôi ở đây là tổng quát hơn --- Làm thế nào để tạo ra sóng tại mỗi dấu thời gian?

Một vài ý tưởng/sửa chữa trong tâm trí tôi:

  1. Đặt biên độ bằng cách nhận một trung bình/ước tính tối đa của biên độ từ tín hiệu miền thời gian của bài hát gốc.
  2. Thay đổi hoàn toàn cách tiếp cận của tôi --- tính toán phép biến đổi phổ/thời gian ngắn của tín hiệu âm thanh của bài hát. cut-off hầu như không/zero-out hoặc nhẹ nhàng tất cả các tần số khác ngoại trừ những tần số trong ca khúc của tôi (hoặc gần với sân của tôi). Và sau đó tính toán phép biến đổi thời gian ngắn nghịch đảo nghịch đảo để nhận tín hiệu miền thời gian.
+0

Bạn có thể tạo một midi có cùng độ dốc/độ dốc/thời gian/giai điệu như giai điệu của bạn, chọn một công cụ tốt cho nó và hiển thị nó trong một chương trình/thư viện mà bạn chọn. cách khác, bạn có thể đưa ra từng lưu ý một phong bì biên độ bắt đầu mạnh (hoặc xây dựng từ 0 nhanh hoặc bắt đầu mạnh), giảm xuống mức giữ yên tĩnh và giảm dần ở cuối. Đây được gọi là phong bì ADSR. – Patashu

+0

Bằng cách nào đó bảng bên mới của tôi như là một dự án nhà không phải là ấn tượng. -1 để khiến tôi cảm thấy mình giống như một vận động viên thượng lưu của Igor (chỉ đùa thôi). –

Trả lời

2

Mặc dù tôi không có quyền truy cập vào hàm synth() của bạn, dựa trên các tham số tôi muốn nói rằng vấn đề của bạn là do bạn không xử lý giai đoạn.

Tức là - không đủ để ghép các đoạn mã dạng sóng với nhau, bạn phải đảm bảo rằng chúng có pha liên tục. Nếu không, bạn đang tạo ra một gián đoạn trong dạng sóng mỗi khi bạn nối hai đoạn mã dạng sóng. Nếu đây là trường hợp, tôi đoán là bạn đang nghe cùng một tần số tất cả các thời gian và rằng nó âm thanh giống như một sawtooth hơn một sinusoid - tôi phải không?

Giải pháp là đặt giai đoạn bắt đầu của đoạn mã n thành giai đoạn cuối của đoạn mã n-1. Dưới đây là một ví dụ về cách bạn sẽ nối hai dạng sóng với tần số khác nhau mà không cần tạo một giai đoạn gián đoạn:

fs = 44100; % sampling frequency 

% synthesize a cosine waveform with frequency f1 and starting additional phase p1 
p1 = 0; 
dur1 = 1; 
t1 = 0:1/fs:dur1; 

x1(1:length(t1)) = 0.5*cos(2*pi*f1*t1 + p1); 

% Compute the phase at the end of the waveform 
p2 = mod(2*pi*f1*dur1 + p1,2*pi); 

dur2 = 1; 
t2 = 0:1/fs:dur2; 
x2(1:length(t2)) = 0.5*cos(2*pi*f2*t2 + p2); % use p2 so that the phase is continuous! 

x3 = [x1 x2]; % this should give you a waveform without any discontinuities 

Lưu ý rằng trong khi điều này sẽ cho bạn một dạng sóng liên tục, quá trình chuyển đổi tần số là tức thời. Nếu bạn muốn tần số dần thay đổi từ time_n thành time_n + 1 thì bạn sẽ phải sử dụng một cái gì đó phức tạp hơn như nội suy McAulay-Quatieri. Nhưng trong mọi trường hợp, nếu đoạn trích của bạn đủ ngắn thì điều này sẽ đủ tốt.

Liên quan đến các nhận xét khác, nếu tôi hiểu chính xác mục tiêu của bạn chỉ là để có thể nghe chuỗi tần số, không phải để âm thanh phát ra như nguồn gốc. Trong trường hợp này, biên độ không phải là quan trọng và bạn có thể giữ nó cố định.

Nếu bạn muốn làm cho âm thanh như nguồn gốc là một câu chuyện hoàn toàn khác và có lẽ nằm ngoài phạm vi của cuộc thảo luận này.

Hy vọng điều này sẽ trả lời câu hỏi của bạn!

+0

@justin cảm ơn rất nhiều vì giải pháp. Điều này thực sự là vấn đề và sau khi sửa chữa nó âm thanh cách tốt hơn. Nhưng tôi cảm thấy tôi cần phải bổ sung một biên độ tốt hơn để thực tế hơn nhưng phạm vi hơi tắt của nó từ câu hỏi của tôi trong bài đăng này. Tôi đọc rằng biên độ cảm nhận phụ thuộc vào tần số (tần số càng cao, biên độ cảm nhận càng cao). Tôi tự hỏi nếu tôi có thể tìm thấy một số mô hình toán học cho sự phụ thuộc này, vì vậy tôi có thể thay đổi biên độ dựa trên sân/tần số thống trị. Có thể được rằng âm thanh sẽ tốt hơn. – cdeepakroy

+0

Ngoài ra, bạn có thể giải thích thêm về nội suy của McAulay-Quatieri hay chỉ cho tôi một bài viết đơn giản hơn - tôi vẫn nghe thấy một chút chirpiness tại điểm chuyển tiếp tín hiệu từ giọng nói sang giọng không được lồng tiếng ngay cả sau khi áp dụng một số làm mịn. – cdeepakroy

+1

Thay đổi biên độ của xoang sẽ chỉ tạo ra một sự khác biệt nhỏ đối với tính thực tế nhận biết (là một từ?) Của tín hiệu tổng hợp - nó vẫn cơ bản giống như một xoang đơn.Nếu bạn muốn nó nghe giống như nguồn gốc thì bạn có hai lựa chọn: có được bộ tổng hợp cho nguồn của bạn (giọng nói/nhạc cụ) và sử dụng trình tự f0 để hướng dẫn tổng hợp hoặc sử dụng thuật toán tách nguồn thay vì thuật toán f0 để tách biệt trực tiếp tín hiệu của nguồn dẫn (ít nhất là cố gắng làm như vậy, đây vẫn là một vấn đề nghiên cứu mở). – jjs

5

Nếu tôi hiểu chính xác, dường như bạn đã có đại diện chính xác về quảng cáo chiêu hàng nhưng vấn đề của bạn là những gì bạn tạo ra không "đủ tốt".

Bắt đầu với phương pháp thứ hai của bạn: lọc ra bất kỳ điều gì nhưng quảng cáo chiêu hàng sẽ không dẫn đến bất kỳ điều gì tốt. Bằng cách loại bỏ tất cả mọi thứ nhưng một vài thùng tần số tương ứng với ước tính độ cao địa phương của bạn, bạn sẽ mất kết cấu của tín hiệu đầu vào, điều làm cho âm thanh trở nên tốt. Trong thực tế, nếu bạn lấy nó đến mức cực đoan và loại bỏ mọi thứ nhưng một mẫu tương ứng với sân và lấy một ifft, bạn sẽ nhận được chính xác một sinusoid, đó là những gì bạn đang làm hiện tại. Nếu bạn muốn làm điều này anyway, tôi khuyên bạn nên thực hiện tất cả điều này bằng cách chỉ cần áp dụng một bộ lọc để tín hiệu thời gian của bạn hơn là đi vào và ra khỏi miền tần số, đó là tốn kém hơn và rườm rà. Bộ lọc sẽ có một điểm ngắt nhỏ xung quanh tần số bạn muốn giữ và điều đó sẽ cho phép âm thanh có kết cấu tốt hơn.

Tuy nhiên, nếu bạn đã có ước tính quảng cáo chiêu hàng và thời lượng mà bạn hài lòng nhưng bạn muốn cải thiện cách hiển thị âm thanh, tôi khuyên bạn chỉ nên thay thế wave sine của mình - âm thanh sẽ luôn phát ra tiếng bíp bíp vấn đề bao nhiêu bạn massage chúng - với một số thực tế ồn ào (hoặc violin hoặc sáo hoặc bất cứ điều gì bạn thích) mẫu cho mỗi tần số trong quy mô. Nếu bộ nhớ là một mối quan tâm hoặc nếu các bài hát bạn đại diện không rơi vào một quy mô ôn hòa (ví dụ như bài hát trung đông), thay vì có một mẫu ồn ào cho mỗi ghi chú của thang đo, bạn chỉ có thể có các mẫu ồn ào cho một vài tần số. Sau đó, bạn sẽ lấy được âm thanh ồn ào ở bất kỳ tần số nào bằng cách thực hiện chuyển đổi tỷ lệ mẫu từ một trong các mẫu ồn ào này. Có một vài mẫu để chọn để thực hiện chuyển đổi mẫu sẽ cho phép bạn chọn tỷ lệ chuyển sang tỷ lệ "tốt nhất" với tần suất bạn cần tạo, vì độ phức tạp của chuyển đổi lấy mẫu phụ thuộc vào tỷ lệ đó. Rõ ràng việc thêm một tỷ lệ chuyển đổi mẫu sẽ có nhiều công việc và đòi hỏi tính toán hơn so với việc chỉ có một ngân hàng mẫu để lựa chọn.

Sử dụng ngân hàng các mẫu thực tế sẽ tạo sự khác biệt lớn về chất lượng của những gì bạn hiển thị. Nó cũng sẽ cho phép bạn có các cuộc tấn công thực tế cho mỗi nốt mới bạn chơi.

Sau đó có, như bạn đề xuất, bạn có thể muốn chơi với biên độ bằng cách theo biên độ tức thời của tín hiệu đầu vào để tạo ra hiển thị nhiều sắc thái hơn của bài hát.

Cuối cùng, tôi cũng sẽ chơi với ước tính thời lượng bạn có để bạn có chuyển tiếp mượt mà hơn từ âm này sang âm thanh tiếp theo. Đoán từ hiệu suất của bạn của tập tin âm thanh của bạn mà tôi rất thích (beep beep beeeeep beep beeep beeeeeeeep) và đồ thị mà bạn hiển thị, có vẻ như bạn có nhiều gián đoạn chèn vào trong rendering của bài hát của bạn. Bạn có thể tránh điều này bằng cách mở rộng các ước tính thời gian để loại bỏ bất kỳ sự im lặng nào ngắn hơn, nói 1 giây. Bằng cách đó, bạn sẽ bảo đảm sự im lặng thực sự từ bài hát gốc nhưng tránh cắt từng nốt của bài hát của bạn.

+0

cảm ơn rất nhiều vì sự phê bình và gợi ý của bạn. Vấn đề là những gì salamon chỉ ra. Tôi đã không đảm bảo rằng các sóng sin liên tiếp theo sau liên tục bằng cách giới thiệu một sự gián đoạn sắc nét giữa chúng. Vì vậy, tín hiệu không có vẻ nghi thức. Sau khi sửa chữa nó âm thanh tốt hơn nhiều. – cdeepakroy

+0

Trên một lưu ý tiếp tuyến về việc thay thế sóng sin bằng tín hiệu thực tế hơn bằng cách sử dụng một ngân hàng mẫu từ một công cụ thực --- là một ngân hàng mẫu có sẵn hoặc có mô hình toán học cho bất kỳ công cụ nào. Rõ ràng, những gì xác định tính độc đáo của âm thanh của một nhạc cụ là các âm bội hoặc sóng hài --- bội số nguyên của tần số cơ bản. Tôi đọc rằng tỷ lệ giữa biên độ của các sóng hài này với tần số cơ bản f mô tả âm thanh của nhạc cụ. theo dõi sân dường như là một sự liên tục của tần số chứ không phải là một lưu ý rời rạc. – cdeepakroy

+0

@cdeepakroy Có và không. Có những tỷ lệ này mà bạn đề cập có xu hướng tương tự đối với các công cụ cùng loại nhưng chúng vẫn thay đổi theo từng công cụ cụ thể, trong mỗi ghi chú và với cách ghi chú khó hoặc nhẹ. Và có năng lượng có xu hướng tích lũy xung quanh bội số nguyên của tần số cơ bản nhưng không có nghĩa là dễ dàng giảm xuống cho chúng: minh họa này nói cho chính nó: http://kozco.com/tech/audacity/piano_G1.jpg. Vì vậy, nếu không có ngân hàng mẫu là ở bàn tay, thêm giai điệu sẽ chắc chắn âm thanh tốt hơn nhưng sẽ vẫn xa âm thanh tự nhiên. – Lolo

1

Bạn có ít nhất 2 vấn đề.

Trước tiên, khi bạn phỏng đoán, phân tích của bạn đã loại bỏ tất cả thông tin biên độ của phần giai điệu của phổ gốc. Bạn sẽ cần một thuật toán để nắm bắt thông tin đó (và không chỉ biên độ của toàn bộ tín hiệu cho đầu vào đa âm, hoặc chỉ của thùng pitch FFT cho bất kỳ âm thanh âm nhạc tự nhiên nào). Đây là một vấn đề không tầm thường, một nơi nào đó giữa khai thác sân melodic và tách nguồn mù.

Thứ hai, âm thanh có âm sắc, bao gồm âm bội và phong bì, ngay cả ở tần số không đổi. Phương pháp tổng hợp của bạn chỉ tạo ra một sinewave duy nhất, trong khi humming có thể tạo ra một loạt các overtones thú vị hơn, bao gồm rất nhiều tần số cao hơn chỉ là sân. Với âm thanh tự nhiên hơn một chút, bạn có thể thử phân tích quang phổ của chính bạn làm rung chuyển một sân và cố gắng tạo lại tất cả hàng tá sóng âm này, thay vì chỉ một, mỗi sóng ở biên độ tương đối thích hợp, khi tổng hợp từng dấu thời gian trong phân tích của bạn. Bạn cũng có thể nhìn vào phong bì biên độ theo thời gian của mình làm ồn một lưu ý ngắn, và sử dụng phong bì đó để điều chỉnh biên độ của bộ tổng hợp của bạn.

+0

đề xuất để phân tích quang phổ của bản thân tôi/tiếng ồn của con người một sân là thú vị. Nhưng tôi tin rằng tôi chỉ có thể làm điều này có lẽ cho các ghi chú trong một vài quãng tám và phân tích chúng. Sau đó, tôi sẽ cần một mô hình toán học mà sẽ cho phép tôi để có được (bằng cách nội suy hoặc ngoại suy) tín hiệu ở bất kỳ tần số liên tục đó là những gì các ca khúc sân của một thuật toán khai thác giai điệu dường như cho tôi. Mô hình toán học có tồn tại không? Tôi mới vào lĩnh vực này, vì vậy nó sẽ rất hữu ích nếu bạn có thể chỉ cho tôi văn học như vậy. – cdeepakroy

+0

Các tài liệu về các thành phần thanh nhạc có thể bao gồm một số mô hình bạn có thể muốn thử. – hotpaw2

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