Установка частоты для аналогового выхода с помощью NI DAQMx
Я пытаюсь вывести сигнал, содержащийся в файле WAV, используя библиотеку NI DAQMx ANSI C. Я использую библиотеку libsnd для чтения файла wav и могу успешно извлечь данные, однако частота выходного сигнала намного выше, чем сам файл wav. Кто-нибудь знает, как можно настроить частоту выходного сигнала. Я использую карту сбора данных PCIe 6351.
Ниже приведен код, который я написал для выполнения этой задачи:
#include<stdio.h>
#include<conio.h>
#include <math.h>
#include <stdlib.h>
#include <windows.h>
#include "NIDAQmx.h"
#include "Sync_AIAO.h"
#include "sndfile.h"
#include "RIB2.h"
int32 fnCreateTask(TaskHandle *AOTaskHandle)
{
int32 error=0;
DAQmxErrChk(DAQmxCreateTask("", AOTaskHandle));
Error:
return error;
}
int main(int argc, char** argv)
{
int i=0;
int32 error=0;
TaskHandle AOtaskHandle = 0;
float64* AIOSample;
float *fWavSample;
SNDFILE *SoundFile;
SF_INFO SoundFileInfo;
int iNoOfSamples=0;
FILE* fp;
//Error code
//Handle to the tasks created
char errBuff[2048]={'\0'};
//DAQmxErrChk(DAQmxCreateTask("",AOtaskHandle));
fnCreateTask(&AOtaskHandle);
//Create an analog out channel
DAQmxErrChk (DAQmxCreateAOVoltageChan(* (&AOtaskHandle),"Dev1/ao1","",-10.0000000,+10.00000,DAQmx_Val_Volts,NULL));
//Set for
//DAQmxErrChk (DAQmxCfgDigEdgeStartTrig(&AOtaskHandle,"ai/StartTrigger",DAQmx_Val_Rising));
SoundFile=sf_open("sine.wav", SFM_READ, &SoundFileInfo);
//Check if file is opened sucessfully
if (SoundFile == NULL)
{
printf("Failed to open the file.\n");
exit(-1);
}
//allocate memory for the buffer that is to hold the wav data:
fWavSample = new float[SoundFileInfo.channels * SoundFileInfo.frames];
iNoOfSamples = SoundFileInfo.channels * SoundFileInfo.frames;
//Read data into the float structure
sf_readf_float(SoundFile, fWavSample, SoundFileInfo.frames);
printf("Float:%d, Float64:%d\n",sizeof(float),sizeof(float64));
//printf("%f\n",fWavSample[0]);
//printf("%f\n",fWavSample[200000]);
AIOSample = new float64[iNoOfSamples];
// fopen_s(&fp,"output.dat","w");
for(i=0;i<SoundFileInfo.channels * SoundFileInfo.frames;i++)
{
// fprintf(fp,"Data[%d]:%f\n",i,fWavSample[i]);
AIOSample[i] = (float64)fWavSample[i];
}
// fclose(fp);
int32 written;
/*calling function that will output the trigger on PFI6*/
//fnSrPlayElectric(); //play electric stimulus
while(1)
{
/*
DAQmxErrChk(DAQmxWriteAnalogF64(AOtaskHandle,(SoundFileInfo.channels * SoundFileInfo.frames),
true, 10.0, DAQmx_Val_GroupByChannel,AIOSample,&written,NULL));
*/
DAQmxErrChk(DAQmxWriteAnalogF64(AOtaskHandle,1000,
true, 10.0, DAQmx_Val_GroupByChannel,AIOSample,&written,NULL));
//Sleep(3000);
}
//Display the error to the user here.
Error:
if( DAQmxFailed(error) )
{
DAQmxGetExtendedErrorInfo(errBuff,2048);
puts(errBuff);
}
getch();
}
Буду признателен за любую помощь, которую я могу получить. Спасибо!
Атула
1 ответ
Прямо сейчас ваша программа записывает сэмплы на карту DAQ по одному настолько быстро, насколько это возможно, и вы отправляете сэмплы в группах по 1000 человек. С точки зрения DAQmx, это "программно-временная" задача, поскольку ОС, планировщик, процессор и другие системные динамики влияют на частоту записи сэмпла на карту.
Поскольку аудиофайлы сэмплируются с постоянной скоростью, вам также необходимо запрограммировать карту DAQ для генерации сэмплов с той же частотой. В терминах DAQmx, использование примера часов называется задачей с аппаратной синхронизацией. DAQmx также поставляется с примерами ANSI C для настройки тактовых импульсов [1]. Взгляните на "Непрерывно генерировать напряжение - внутренние часы", который, вероятно, имеет сокращенное название на диске, и как он использует функцию DAQmxCfgSampClkTiming
[2]. Также есть больше информации о том, как работает тайминг для DAQmx онлайн [3].
Например, если ваш аудиофайл сэмплируется с частотой 44,1 кГц, вам необходимо установить одинаковую тактовую частоту. Однако следует помнить, что 6351 имеет частоту 100 МГц [4] и делит его на целые числа, чтобы получить более низкие тактовые частоты дискретизации. Таким образом, для этого примера 44,1 кГц ближайшая частота, которую вы можете получить, составляет 44,111 кГц (100 МГц / 2267) или 44,091 кГц (100 МГц / 2268). Вы можете проверить фактическую частоту дискретизации, используя DAQmxGetSampClkRate
[5] после того, как вы настроите его - DAQmx приведёт его к допустимому значению.
[1] Примеры сбора данных NI-DAQmx на основе текста:: ANSI C
http://www.ni.com/white-paper/6999/en/[2] Справочная информация по NI-DAQmx C:: DAQmxCfgSampClkTiming
http://zone.ni.com/reference/en-XX/help/370471W-01/daqmxcfunc/daqmxcfgsampclktiming[3] Сроки, аппаратное обеспечение и программное обеспечение
http://zone.ni.com/reference/en-XX/help/370466V-01/TOC11.htm[4] Руководство пользователя для серии X:: Маршрутизация часов (стр. 183)
http://digital.ni.com/manuals.nsf/websearch/82BB2FBF407E178586257D15006F596C[5] Справочная информация по NI-DAQmx C:: DAQmxGetSampClkRate
http://zone.ni.com/reference/en-XX/help/370471W-01/mxcprop/func1344