Не понимаю вот это "Немного расскажу почему так получается. как ты наверное знаешь ДПФ принимает на вход комплексный сигнал и на выходе также получается компл..." Грубо говоря входной сигнал нужно преобразовать в комплексный вид чтобы скормить DFT ?
Действительные числа - это подмножество комплексных, некорректно говорить так они по умолчанию комплексные. Действительный сигнал, это комплексный с зануленой мнимой частью.
Просто я экспериментировал вот с этим DFT, у него на входе сигнал не комплексный x[n], насколько я понимаю комплексный x[n]+j[n] Код (Text): #include <stdio.h> #include <stdlib.h> #include <math.h> // N is assumed to be greater than 4 and a power of 2 #define N 64 #define PI2 6.2832 // Twiddle factors (64th roots of unity) const float W[] = { 1.00000, 0.99518, 0.98079, 0.95694, 0.92388, 0.88192, 0.83147, 0.77301, 0.70711, 0.63439, 0.55557, 0.47139, 0.38268, 0.29028, 0.19509, 0.09801, -0.00000,-0.09802,-0.19509,-0.29029,-0.38269,-0.47140,-0.55557,-0.63440, -0.70711,-0.77301,-0.83147,-0.88192,-0.92388,-0.95694,-0.98079,-0.99519, -1.00000,-0.99518,-0.98078,-0.95694,-0.92388,-0.88192,-0.83146,-0.77300, -0.70710,-0.63439,-0.55556,-0.47139,-0.38267,-0.29027,-0.19508,-0.09801, 0.00001, 0.09803, 0.19510, 0.29030, 0.38269, 0.47141, 0.55558, 0.63440, 0.70712, 0.77302, 0.83148, 0.88193, 0.92388, 0.95694, 0.98079, 0.99519 }; int main() { // time and frequency domain data arrays int n, k; // time and frequency domain indices float x[N]; // discrete-time signal, x float Xre[N/2+1], Xim[N/2+1]; // DFT of x (real and imaginary parts) float P[N/2+1]; // power spectrum of x // Generate random discrete-time signal x in range (-1,+1) srand(time(0)); for (n=0 ; n<N ; ++n) x[n] = (((2.0 * rand()) / RAND_MAX) - 1.0+sin(PI2*n*16/N))/2; // for (n=0 ; n<N ; ++n) x[n] = ((2.0 * rand()) / RAND_MAX) - 1.0; // Calculate DFT and power spectrum up to Nyquist frequency int to_sin = 3*N/4; // index offset for sin int a, b; for (k=0 ; k<=N/2 ; ++k) { Xre[k] = 0; Xim[k] = 0; a = 0; b = to_sin; for (n=0 ; n<N ; ++n) { Xre[k] += x[n] * W[a%N]; Xim[k] -= x[n] * W[b%N]; a += k; b += k; } P[k] = (sqrt(Xre[k]*Xre[k] + Xim[k]*Xim[k]))/16; } // Output results to MATLAB / Octave M-file for plotting FILE *f = fopen("dftplots.m", "w"); fprintf(f, "n = [0:%d];\n", N-1); fprintf(f, "x = [ "); for (n=0 ; n<N ; ++n) fprintf(f, "%f ", x[n]); fprintf(f, "];\n"); fprintf(f, "Xre = [ "); for (k=0 ; k<=N/2 ; ++k) fprintf(f, "%f ", Xre[k]); fprintf(f, "];\n"); fprintf(f, "Xim = [ "); for (k=0 ; k<=N/2 ; ++k) fprintf(f, "%f ", Xim[k]); fprintf(f, "];\n"); fprintf(f, "P = [ "); for (k=0 ; k<=N/2 ; ++k) fprintf(f, "%f ", P[k]); fprintf(f, "];\n"); fprintf(f, "subplot(3,1,1)\nplot(n,x)\n"); fprintf(f, "xlim([0 %d])\n", N-1); fprintf(f, "subplot(3,1,2)\nplot([0:%d],Xre,[0:%d],Xim)\n", N/2, N/2); fprintf(f, "xlim([0 %d])\n", N/2); fprintf(f, "subplot(3,1,3)\nstem([0:%d],P)\n", N/2); fprintf(f, "xlim([0 %d])\n", N/2); fclose(f); // exit normally return 0; }
Ну дело в том что комплексный сигнал можно сформировать вне компьютера, и подать на стерео вход, на одном канале x[n], на другом q[n]
угу. ну, что значит "простецкий"? в общем и целом коды-то типичные, различаются лишь по поддерживаемым аудиоформатам и используемым либам. если уж так жаждешь разобраться в кодирование звука, так та же fftw есь фосс и ты её можешь собрать под вынь. http://www.fftw.org/install/windows.html а куча фосса тута https://sourceforge.net/directory/audio-video/sound/audio-capture/os:windows/
Ну подаешь, выполняешь ДПФ и извлекаешь два спектра. Можешь не делать так сделав 2 преобразования подряд. В чем вопрос? Описал я это чтобы стала понятна суть как это работает "на пальцах".
Вот функция чтения аудио интерфейса, как тут задаётся то с какого входа читать будет , с линейного или микрофонного ? Непонятно семпл за раз читается один с одного канала или за раз оба канала в одном семле чтоли ? Код (Text): // capture 1s from sound card void capture1s(short *samples) { int err; int rate = CAP_RATE; // capture a chunk of 1 second if ((err = snd_pcm_readi(capture_handle, samples, rate)) != rate) { printf("read from audio interface failed (%s)\n", snd_strerror(err)); exit(1); }
snd_pcm_t *capture_handle, *playback_handle; if ((err = snd_pcm_open(&capture_handle, sndcard, SND_PCM_STREAM_CAPTURE, 0)) < 0) if ((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0) { if ((err = snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { if ((err = snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) { if ((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &rate, 0)) < 0) { if ((err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, channels)) < 0) { if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0) { if ((err = snd_pcm_prepare(capture_handle)) < 0) { snd_pcm_close(capture_handle); if ((err = snd_pcm_readi(capture_handle, samples, rate)) != rate) {
Прошелся поиском, по всем файлам capture_handle это указатель, но чему он равен я так и не понял, нет присваивания нигде,
Открываешь устройство через WaveInOpen (задаешь колбек механизм), заполняешь буфера WAVEHDR/waveInPrepareHeader и отправляешь их драйверу waveInAddBuffer. Далее стартуешь процесс захвата waveInStart. Далее через колбек механизм периодически ловишь заполненные буфера (PCM) и отправляешь их драйверу. Все. Прочти доку. И это только один из кучи вариантов потоковой записи.