Modyfikacja programu do przetwornika analogowo-cyfrowego

0

Witam
Posiadam przetwornik analogowo-cyfrowy do ktorego podpiety jest mikrofon. Mam do tego program ktory pobiera probki napiec i wyswietla w konsoli. Nie jestem specjalista w programowaniu a potrzebuje zeby program pokazywal wyniki w decybelach. Jezeli ktos bylby w stanie mi pomoc, naprowadzic w jakikolwiek sposob w ktorym miejscu sie za to wziac bylbym bardzo wdzieczny.



```#include <stdlib.h>
#include <stdio.h>
#include "../../../inc/bdaqctrl.h"
#include "../inc/compatibility.h"
//-----------------------------------------------------------------------------------
// Configure the following parameters before running the demo
//-----------------------------------------------------------------------------------
#define deviceDescription L"USB-4716,BID#0"
const wchar_t* profilePath = L"C:/Users/Miłosz/Desktop/usb4716.xml";
#define startChannel  0
#define channelCount  1
#define sectionLength 1024
#define sectionCount  0
#define clockRate       1000

#define USER_BUFFER_SIZE  channelCount*sectionLength
double  Data[USER_BUFFER_SIZE];
int32   returnedCount = 0;

void BDAQCALL OnDataReadyEvent         (void * sender, BfdAiEventArgs * args, void *userParam);
void BDAQCALL OnOverRunEvent           (void * sender, BfdAiEventArgs * args, void *userParam);
void BDAQCALL OnCacheOverflowEvent     (void * sender, BfdAiEventArgs * args, void *userParam);
void BDAQCALL OnStoppedEvent           (void * sender, BfdAiEventArgs * args, void *userParam);

void waitAnyKey()
{
   do {SLEEP(1);} while (!kbhit());
}

int main(int argc, char* argv[])
{
   ErrorCode ret = Success;
   Conversion * conversion = NULL;
   Record * record = NULL; 

   // Step 1: Create a 'WaveformAiCtrl' for Waveform AI function.
   WaveformAiCtrl * wfAiCtrl = WaveformAiCtrl_Create();

   // Step 2: Set the notification event Handler by which we can known the state of operation effectively.
   WaveformAiCtrl_addDataReadyHandler     (wfAiCtrl, OnDataReadyEvent,         NULL);
   WaveformAiCtrl_addOverrunHandler       (wfAiCtrl, OnOverRunEvent,           NULL);
   WaveformAiCtrl_addCacheOverflowHandler (wfAiCtrl, OnCacheOverflowEvent,     NULL);
   WaveformAiCtrl_addStoppedHandler       (wfAiCtrl, OnStoppedEvent,           NULL);

   do 
   {
      // Step 3: Select a device by device number or device description and specify the access mode.
      // in this example we use ModeWrite mode so that we can fully control the device, including configuring, sampling, etc.
      DeviceInformation devInfo;
      devInfo.DeviceNumber = -1;
      devInfo.DeviceMode   = ModeWrite;
      devInfo.ModuleIndex  = 0;
      wcscpy(devInfo.Description, deviceDescription);
      ret = WaveformAiCtrl_setSelectedDevice(wfAiCtrl, &devInfo);
      CHK_RESULT(ret);
      ret = WaveformAiCtrl_LoadProfile(wfAiCtrl, profilePath);//Loads a profile to initialize the device.
      CHK_RESULT(ret);

      // Step 4: Set necessary parameters
      conversion = WaveformAiCtrl_getConversion(wfAiCtrl);
      ret = Conversion_setChannelStart(conversion, startChannel);
      CHK_RESULT(ret);
      ret= Conversion_setChannelCount(conversion, channelCount);
      CHK_RESULT(ret);
      ret = Conversion_setClockRate(conversion, clockRate);
      CHK_RESULT(ret);

        record = WaveformAiCtrl_getRecord(wfAiCtrl);
      ret = Record_setSectionCount(record, sectionCount);//The 0 means setting 'streaming' mode.
      CHK_RESULT(ret);
      ret = Record_setSectionLength(record, sectionLength);
      CHK_RESULT(ret);

      // Step 5: The operation has been started.
        // We can get samples via event handlers.
      ret = WaveformAiCtrl_Prepare(wfAiCtrl);
        CHK_RESULT(ret);
        ret = WaveformAiCtrl_Start(wfAiCtrl);
      CHK_RESULT(ret);

      // Step 6: The device is acquiring data.
      printf("Streaming AI is in progress.\nplease wait...  any key to quit!\n\n");
      do
      {
         SLEEP(1);
      } while (!kbhit());

      // step 7: Stop the operation if it is running.
      ret = WaveformAiCtrl_Stop(wfAiCtrl);
      CHK_RESULT(ret);
   } while (FALSE);

   // Step 9: Close device, release any allocated resource.
   WaveformAiCtrl_Dispose(wfAiCtrl);

   // If something wrong in this execution, print the error code on screen for tracking.
   if (BioFailed(ret))
   {
      printf("Some error occurred. And the last error code is 0x%X.\n", ret);
      waitAnyKey();// wait any key to quit!
   }
   return 0;
}
//The function is used to deal with 'DataReady' Event.
void BDAQCALL OnDataReadyEvent (void * sender, BfdAiEventArgs * args, void *userParam)
{
   int i = 0;
   int getDataCount = 0;
   WaveformAiCtrl * waveformAiCtrl = NULL;
   waveformAiCtrl = (WaveformAiCtrl *)sender;
   getDataCount = MinValue(USER_BUFFER_SIZE, args->Count);
   WaveformAiCtrl_GetDataF64(waveformAiCtrl, getDataCount, Data, 0, &returnedCount, NULL, NULL, NULL);
    printf("Streaming AI get data count is  %d\n", returnedCount);
    printf("the first sample for each Channel are:\n");
   for(i = 0; i < channelCount; ++i)
   {
      printf("channel %d:%10.6f \n",i + startChannel, Data[i]);   
   }
}
//The function is used to deal with 'OverRun' Event.
void BDAQCALL OnOverRunEvent (void * sender, BfdAiEventArgs * args, void *userParam)
{
   printf("Streaming AI Overrun: offset = %d, count = %d\n", args->Offset, args->Count);
}
//The function is used to deal with 'CacheOverflow' Event.
void BDAQCALL OnCacheOverflowEvent (void * sender, BfdAiEventArgs * args, void *userParam)
{
   printf(" Streaming AI Cache Overflow: offset = %d, count = %d\n", args->Offset, args->Count);
}
//The function is used to deal with 'Stopped' Event.
void BDAQCALL OnStoppedEvent (void * sender, BfdAiEventArgs * args, void *userParam)
{
   printf("Streaming AI stopped: offset = %d, count = %d\n", args->Offset, args->Count);
}
1

Jeśli mnie pamięć nie myli, wzór do obliczania wartości w dB wygląda tak: 20log10 |wartość_próbki|. Znajdź w buforze zwróconym w OnDataReadyEvent największe (bezwzględne) wartości dla każdego kanału i potraktuj je tym wzorem.

Z tego, co widzę, bufor jest typu double[], więc zakładam, że wartości próbek mieszczą się w zakresie [-1, 1]. Jeśli jest inaczej, powinieneś wartości znormalizować do tego zakresu, po to żeby mieć na wyjściu poprawne wartości dB.

0

A jak wyglada sprawa z zapisem tych odczytow do pliku?
Sama idea zapisywania w prostych programach jest mi znana ale w przypadku gdy te dane sa w petli jak w tym programie nie do konca wiem jak to ma wygladac.
Wszystkie komendy trafiaja do funkcji gdzie drukuje w konsoli te dane?

0

O jakie zapisywanie Ci chodzi? W stanie surowym, czy w jakimś konkretnym formacie?

WaveformAiCtrl - co to za API?

0

Ale w dB względem czego? 1V, czyli tzw. dBV, czy może chcesz to przeliczyć na moc względem 1Wata (miliwata? mikrowata?)? Bo decybele to jest skala względna, tzn. odnosisz się w niej do jakiejś referencji...

0

Do V ale problem rozwiazany, ostateczmie mialem przeliczyc tylko do cisnienia

0
0x666 napisał(a):

O jakie zapisywanie Ci chodzi? W stanie surowym, czy w jakimś konkretnym formacie?

WaveformAiCtrl - co to za API?

Szczerze to nie mam pojecia, program byl dostarczony razem z tym przetwornikiem usb4716, wykorzystalem go do odczytu danych tylko musialem wprowadzic pare zmian wlasnie typu zamiana odczytanego napiecia na cisnienie, zapis tych danych. Jezeli chodzi o zapis to najprostszy w pliku tekstowym, zeby te dane po prostu gdzies sie zgromadzily i byly mozliwe do odczytania pozniej

0

Wartości próbek chcesz zapisywać w postaci tekstowej? Pomysł raczej średni...

Zapis (w trybie binarnym) może wyglądać tak:

void BDAQCALL OnDataReadyEvent (void * sender, BfdAiEventArgs * args, void *userParam)
{
    double buffer[USER_BUFFER_SIZE];
    int getDataCount = MinValue(USER_BUFFER_SIZE, args->Count);
    WaveformAiCtrl * waveformAiCtrl = (WaveformAiCtrl*)sender;

    WaveformAiCtrl_GetDataF64(waveformAiCtrl, getDataCount, Data, 0, &returnedCount, NULL, NULL, NULL);
    fwrite( buffer, sizeof(double), returnedCount, fs); // `fs` to wcześniej otwarty plik w trybie binarnym
}

Powinieneś poczytać w dokumentacji, czy w OnDataReadyEvent możesz używać funkcji do obsługi plików czy innych systemowych. W większości bibliotek audio w tego typu funkcjach zwrotnych nie można używać praktycznie żadnej funkcji systemowej (z paroma wyjątkami).

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0