/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
realtidsprocessering af audiosignal fra ly~
Fra : Heureka


Dato : 25-10-02 17:28

Hejsa

Jeg har længe ledt efter noget C++ kode som kan behandle et audiosignal fra
lydkortet i realtid så jeg kan teste nogen DSP algoritmer. Det skal skal
helst ikke være blokprocessering men istedet foregå på sample-by-sample
"metoden"!

Jeg håber at nogen af jer kan hjælpe mig. Jeg har søgt meget omfattende på
google men uden held

Thomas



 
 
Simon Strandgaard (26-10-2002)
Kommentar
Fra : Simon Strandgaard


Dato : 26-10-02 01:03



Heureka (26-10-2002)
Kommentar
Fra : Heureka


Dato : 26-10-02 10:56

Hej igen

herligt med et svar på mit indlæg. Ja, jeg glemte at oplyse at jeg kører med
windows XP.

Thomas :)

"Simon Strandgaard" <neoneye@diku.dk> wrote in message
news:Pine.LNX.4.44L0.0210260155180.1718-100000@ask.diku.dk...
> On Fri, 25 Oct 2002, Heureka wrote:
>
> > Jeg har længe ledt efter noget C++ kode som kan behandle et audiosignal
fra
> > lydkortet i realtid så jeg kan teste nogen DSP algoritmer. Det skal skal
> > helst ikke være blokprocessering men istedet foregå på sample-by-sample
> > "metoden"!
>
> Dette er meget system-specifikt. For at vi kan hj'lpe dig m? du fort'lle
> os lidt om hvilket system du k>rer. Windows98, WindowsNT, Linux, FreeBSD?
>
> Et godt r?d er at kigge p? SDL.
> http://sdl.org
>
> Med SDL kan du b?de lave lyd, grafik, tr?de, input.
> Er dog ikke 100% klar over om SDL kan udtr'kke data fra microfonen?
>
> Held og lykke
> Simon Strandgaard
>



Thomas Lykkeberg (26-10-2002)
Kommentar
Fra : Thomas Lykkeberg


Dato : 26-10-02 11:16

On Sat, 26 Oct 2002 02:03:21 +0200, Simon Strandgaard
<neoneye@diku.dk> wrote:

>On Fri, 25 Oct 2002, Heureka wrote:
>
>> Jeg har længe ledt efter noget C++ kode som kan behandle et audiosignal fra
>> lydkortet i realtid så jeg kan teste nogen DSP algoritmer. Det skal skal
>> helst ikke være blokprocessering men istedet foregå på sample-by-sample
>> "metoden"!
Dette er ikke blot meget system specifikt, men jeg vil påstå at
realtids behandling af "sample-by-sample" på en PC med et tvunget
tidsdelings operativsystem ikke kan give noget godt resultat. Jeg
mener at interrupt latancy i eks. vis. Windows kan blive op til 20ms
med en 500MHz CPU. Hvis du vil processerer et 48kHz samplet signal,
vil der jo komme et interrupt hvert ca. 21us, altså 1000 gange så
hurtigt som interruptets maksimale latancy. En 500MHz CPU ville nok
kunne afvikle en maskin intruktion hvert 10ns (godt 2100 maskin cycles
til at håndterer interrupt og data processering). Til sammenligning
kan man tage en DSP (33MHz ADSP2181 fra ADI) som vil kunne afvikle
instruktioner hvert 30ns, men den har jo heller ikke et operativsystem
i Windows klassen at slås med .

Problemet ligger i den forsinkelse der er i Windows kernen fra et DMA
interrupt indtræffer, til det rent faktisk bliver signaleret til
user/kernel SW. Du skal nok have fat i en ULTRA hurtig maskine hvis
det skal være sample-by-sample du vil implementerer. Brug dog en lille
buffer på 100 samples (det du kalder blokprocessering) eller sådan
noget i den stil. Det vil selvfølgelig give et delay på godt 2ms.

Der er skam en god grund til at man benytter DSP'ere. De fleste bruger
overdimensionerede DSP'ere til at simulerer deres algoritmer med i
dag. Da en DSP mange gange er MEGET hurtigere end en eks. vis en
Pentium CPU. Husk at en DSP typisk er en meget dedikeret processor.

Køb dig dog et lille EZ-KIT fra ADI med enten en 21xx/21xxx eller
BlackFin DSP på. Det koster vel omkring 2k hvis du da ikke kender en
som vil af med et billigere. Her kan man med lidt snidle også få fat i
en GCC compiler. Jeg har en GCC til eks. vis 21xx versionen (G21), har
ikke kunnet få fat i en til mit SHARC board (G21K). Man skal bare lige
huske at man nok kommer længst med assembler til disse typer CPU'er.

Prøv iøvrigt at spørge i comp.dsp (engelsk), her sidder nogle heftige
DSP hoveder (ADI/TI osv.) som sikkert vil kunne give dig nogle fif til
hvordan du skal gribe det an, hvis du VIL lave realtids simulering på
en PC.

/Thomas

/Thomas

Heureka (26-10-2002)
Kommentar
Fra : Heureka


Dato : 26-10-02 12:15

Hej Thomas

Jeg er meget taknemlig for din mail :)

læs venligst mellem dine egne linjer!

> Dette er ikke blot meget system specifikt, men jeg vil påstå at
> realtids behandling af "sample-by-sample" på en PC med et tvunget
> tidsdelings operativsystem ikke kan give noget godt resultat. Jeg
> mener at interrupt latancy i eks. vis. Windows kan blive op til 20ms
> med en 500MHz CPU. Hvis du vil processerer et 48kHz samplet signal,
> vil der jo komme et interrupt hvert ca. 21us, altså 1000 gange så
> hurtigt som interruptets maksimale latancy. En 500MHz CPU ville nok
> kunne afvikle en maskin intruktion hvert 10ns (godt 2100 maskin cycles
> til at håndterer interrupt og data processering). Til sammenligning
> kan man tage en DSP (33MHz ADSP2181 fra ADI) som vil kunne afvikle
> instruktioner hvert 30ns, men den har jo heller ikke et operativsystem
> i Windows klassen at slås med .

Godt, det var rart at vide. Kendte i forvejen ikke til "tiderne"

> Problemet ligger i den forsinkelse der er i Windows kernen fra et DMA
> interrupt indtræffer, til det rent faktisk bliver signaleret til
> user/kernel SW. Du skal nok have fat i en ULTRA hurtig maskine hvis
> det skal være sample-by-sample du vil implementerer. Brug dog en lille
> buffer på 100 samples (det du kalder blokprocessering) eller sådan
> noget i den stil. Det vil selvfølgelig give et delay på godt 2ms.

Ja, forsinkelsen(groupdelayet) er for så vidt ligegyldig.

> Der er skam en god grund til at man benytter DSP'ere. De fleste bruger
> overdimensionerede DSP'ere til at simulerer deres algoritmer med i
> dag. Da en DSP mange gange er MEGET hurtigere end en eks. vis en
> Pentium CPU. Husk at en DSP typisk er en meget dedikeret processor.

Det med overdimensionerede DSP'er ved jeg ikke helt. På arbejdet hvor jeg
programmerer diverse EZ-kit's fra AD er det hændt et par gange at jeg har
"manglet" clockcycles og det har sågar været med en samplingfrekvens på
16kHz.

> Køb dig dog et lille EZ-KIT fra ADI med enten en 21xx/21xxx eller
> BlackFin DSP på. Det koster vel omkring 2k hvis du da ikke kender en
> som vil af med et billigere. Her kan man med lidt snidle også få fat i
> en GCC compiler. Jeg har en GCC til eks. vis 21xx versionen (G21), har
> ikke kunnet få fat i en til mit SHARC board (G21K). Man skal bare lige
> huske at man nok kommer længst med assembler til disse typer CPU'er.

Har allerede en 21065L liggende foran mig som jeg ikke bruger(gider ikke
rode med boardet efter 8 timer på arbejdet) - det er for øvrigt til salg.:)

Findes der en GCC til 21xxx? det lyder meget spændende. Jeg er nu ret glad
for Visual DSP++ V2.0 som vi har på arbejdet, men som desværre er en
serverlicens så jeg kan ikke bruge det hjemme.

> Prøv iøvrigt at spørge i comp.dsp (engelsk), her sidder nogle heftige
> DSP hoveder (ADI/TI osv.) som sikkert vil kunne give dig nogle fif til
> hvordan du skal gribe det an, hvis du VIL lave realtids simulering på
> en PC.

Kender godt comp.dsp! Ja, der er nogle meget kvikke/begavede mennesker der.

For nu at vende tilbage til C++ kode spørgsmålet:

Hvis jeg nu ønsker løsningen med en buffer, har du koden så jeg kan komme
igang. Jeg har ikke programmeret i C++ i meget lang tid og ku' godt tænke
mig at mestre det hvilket i virkeligheden er årsagen til jeg er startet på
dette her projekt.?

Tak igen for din mail!

Thomas



Thomas Lykkeberg (26-10-2002)
Kommentar
Fra : Thomas Lykkeberg


Dato : 26-10-02 12:41

On Sat, 26 Oct 2002 13:15:29 +0200, "Heureka" <stoltzo@hotmail.com>
wrote:

>For nu at vende tilbage til C++ kode spørgsmålet:
>
>Hvis jeg nu ønsker løsningen med en buffer, har du koden så jeg kan komme
>igang. Jeg har ikke programmeret i C++ i meget lang tid og ku' godt tænke
>mig at mestre det hvilket i virkeligheden er årsagen til jeg er startet på
>dette her projekt.?
Hej igen, jeg har nok misforstået dit spørgsmål lidt. Jeg har da selv
lavet nogle lydkorts ekperimeter før i tiden, men det var nu i C kode.
Jeg har en lille stump kode som tester WAVE OUT, men det kan vel
simplet rettes til noget WAVE IN i stedet for. Her er den stump så

Koden gør simpelthen det at den åbner et "handle" til en WAVE OUT
enhed, herefter genereres en buffer med 2048 samples af random data.
Disse data sendes så til WAVE OUT enheden, og en ny buffer
genereres... osv. Dette gentages 50 gange. Jeg håber at du med lidt
hjælp fra MSDN...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/wave_4i2b.asp

kan finde ud af noget.

/Thomas



#include <windows.h>

int main(int argc, char *argv[], char *envp[])
{
   HWAVEOUT hWaveOut;
   MMRESULT result;
   WAVEFORMATEX waveFmtEx;
   WAVEHDR waveHdr1;
   WAVEHDR waveHdr2;
   WORD *pData;
   WORD n;

   waveFmtEx.cbSize = 0;
   waveFmtEx.nChannels = 2;
   waveFmtEx.wFormatTag = WAVE_FORMAT_PCM;
   waveFmtEx.wBitsPerSample = 16;
   waveFmtEx.nSamplesPerSec = 44100;
   waveFmtEx.nBlockAlign = 4;
   waveFmtEx.nAvgBytesPerSec = 4 * 44100;

   result =
waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveFmtEx,0,0,CALLBACK_NULL);

waveHdr1.lpData = (LPSTR)GlobalAlloc(GPTR,40960);
   waveHdr1.dwBufferLength = 40960;
   waveHdr1.dwFlags = 0;


waveHdr2.lpData = (LPSTR)GlobalAlloc(GPTR,4096);
   waveHdr2.dwBufferLength = 4096;
   waveHdr2.dwFlags = 0;

   pData = (WORD *)waveHdr1.lpData;
   for(n=0;n<20480;n++)
      *pData++ = (WORD)rand();


   pData = (WORD *)waveHdr2.lpData;
   for(n=0;n<2048;n++)
      *pData++ = (WORD)rand();

   result =
waveOutPrepareHeader(hWaveOut,&waveHdr1,sizeof(WAVEHDR));
   result =
waveOutPrepareHeader(hWaveOut,&waveHdr2,sizeof(WAVEHDR));

   waveHdr1.dwFlags |= (WHDR_BEGINLOOP | WHDR_ENDLOOP);
   waveHdr1.dwLoops = 5;

   result = waveOutWrite(hWaveOut,&waveHdr1,sizeof(WAVEHDR));

   waveHdr2.dwFlags |= (WHDR_BEGINLOOP | WHDR_ENDLOOP);
   waveHdr2.dwLoops = 50;

   result = waveOutWrite(hWaveOut,&waveHdr2,sizeof(WAVEHDR));
   
   while(!(waveHdr2.dwFlags & WHDR_DONE))
   {
      /* Wait for the buffer to finish */
   }

   result = waveOutClose(hWaveOut);

   GlobalFree(waveHdr1.lpData);
   GlobalFree(waveHdr2.lpData);

   return 0;
}


Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste