Это мой первый пост здесь, и я довольно плохо знаком с программированием, особенно с C. Пару недель спустя go я начал работать с Книгой аудиопрограммирования (пресса MIT) и расширил некоторые примеры, чтобы попытаться понять вещи дальше.
Я думаю, что мой вопрос заключается в том, как я пытаюсь передать данные (полученные от пользователя в функции инициализации) в обратный вызов PortAudio. Я чувствую, что то, что я сделал, ничем не отличается от примеров (как из книги, так и из примеров PortAudio, таких как paex_sine. c), но по какой-то причине я не могу работать с моим кодом, и я трахаюсь моя голова у стены пытается понять почему. Я пытался довольно интенсивно искать решения или примеры кода для изучения, но я вроде не знаю, чего не знаю, так что это мало что дало.
Как получить пользовательские данные в обратном вызове?
Я просто не понимаю, как работают указатели и структуры, и пытаюсь заставить их делать то, чего они не хотят?
Или я просто пропускаю что-то действительно очевидное?
Следующий код либо дает действительно высокочастотный выходной сигнал, короткие высокочастотные сигналы или нет (слышимый) выходной сигнал:
#include <stdio.h>
#include <math.h>
#include "portaudio.h"
#define FRAME_BLOCK_LEN 64
#define SAMPLING_RATE 44100
#define TWO_PI (3.14159265f * 2.0f)
PaStream *audioStream;
double si = 0;
typedef struct
{
float frequency;
float phase;
}
paTestData;
int audio_callback (const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeinfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
// data->frequency = 400;
for(i = 0; i < framesPerBuffer; i++){
si = TWO_PI * data->frequency / SAMPLING_RATE; // calculate sampling-incr
*out++ = sin(data->phase);
*out++ = sin(data->phase);
data->phase += si; // add sampling-incr to phase
}
return paContinue;
}
void init_stuff()
{
float frequency;
int i;
PaStreamParameters outputParameters;
paTestData data;
printf("type the modulator frequency in Hz: ");
scanf("%f", &data.frequency); // get modulator frequency
printf("you chose data.frequency %.2f\n",data.frequency);
data.phase = 0.0;
printf("initializing Portaudio. Please wait...\n");
Pa_Initialize(); // initialize Portaudio
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
Pa_OpenStream( // open paStream object
&audioStream, // portaudio stream object
NULL, // input params
&outputParameters, // output params
SAMPLING_RATE, // SampleRate
FRAME_BLOCK_LEN, // frames per buffer
paNoFlag, // set no Flag
audio_callback, // callbak function address
&data ); // user data
Pa_StartStream(audioStream); // start the callback mechanism
printf("running... press space bar and enter to exit\n");
}
void terminate_stuff()
{
Pa_StopStream(audioStream); // stop callback mechanism
Pa_CloseStream(audioStream); // destroy audio stream object
Pa_Terminate(); // terminate portaudio
}
int main(void)
{
init_stuff();
while(getchar() != ' ') Pa_Sleep(100);
terminate_stuff();
return 0;
}
Uncommenting data->frequency = 400;
по крайней мере воспроизводит синусоидальный сигнал 400 Гц, но это игнорирует любой пользовательский ввод, сделанный в init_stuff()
Если я поместил printf("%f\n",data->frequency);
внутри обратного вызова, он напечатает 0,000000 или что-то вроде -146730090609497866240.000000. Это довольно непредсказуемо, и это действительно заставляет меня думать, что это связано с указателем.
Моя цель этого кода - в конечном итоге включить генераторы огибающей для изменения высоты тона и, возможно, включить осцилляторы с волновой графикой, чтобы я не вычислял sin (x) за каждую итерацию. Я могу заставить работать конверты и волновые таблицы, используя блокирующий API, такой как portsf, который используется в книге, но попытка адаптировать любой из этого кода из предыдущих глав для использования обратных вызовов PortAudio превращает мой мозг в mu sh.
Большое спасибо!