/ 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
Bech_bb 500
kyllekylle 500
jdjespers.. 500
gibson 300
scootergr.. 300
molokyle 287
10  strarup 270
Udfyldning af noget meningsfyldt i en soun~
Fra : Jacob Jensen


Dato : 15-08-06 20:13

Er der nogle her der har rigtigt godt styr på DirectSound? Hjælp :)

Jeg har at gøre med en "LPDIRECTSOUNDBUFFER8". Først ville jeg hente noget
data fra en wave-fil, men det er vist ikke helt trivielt, så nu ville jeg
prøve at syntetisere noget PCM-lyd.

Så jeg gjorde det her:

1) Jeg åbnede min lyd-editor.
2) Lavede 3 sekunders lyd med en ren 440Hz tone.
3) Gemte som PCM. 8bit, mono, 22050Hz
4) Åbnede i en hex-editor og fandt data.

Data ser ud som i array'et neden for. Jeg har prøvet at plotte værdierne og
det giver en fin sinus-kurve

Nu vil jeg så skrive disse værdier, igen og igen, ned i min buffer så alle 3
sekunders lyd bliver fyldt ud. Jeg har kaldt Lock() på min sound buffer og
jeg har fået (går jeg ud fra) en valid adresse hvortil jeg må skrive (i
dette tilfælde har jeg bedt om at skrive fra starten af bufferen). Det er
variablen "writeAddr" nedenfor. Det virker bare ikke. Kan nogle gennemskue
det? Skulle det ikke kunne lade sig gøre sådan her?

int index = 0;
byte wave[] = {0xC0, 0xBF, 0xBD, 0xBA, 0xB6, 0xB1, 0xAC, 0xA6, 0x9F, 0x97,
0x90, 0x88, 0x80, 0x78, 0x70, 0x68, 0x61, 0x5A, 0x54, 0x4E, 0x4A, 0x46,
0x43, 0x41, 0x40, 0x3F, 0x40, 0x42, 0x45, 0x49, 0x4E, 0x53, 0x59, 0x60,
0x67, 0x6F, 0x77, 0x7F, 0x87, 0x8F, 0x96, 0x9E, 0xA4, 0xAB, 0xB0, 0xB5,
0xB9, 0xBC, 0xBE, 0xBF};

unsigned int fourBytes = 0;

BYTE* writeHere = (BYTE*)writeAddr;
for(int i=0; i<numBytesToWrite; i+=4)
{
fourBytes = wave[index];
for(int j=1; j<4; j++)
{
fourBytes = fourBytes << 8;
fourBytes += wave[index+j];
}
*(writeHere+i) = fourBytes;
index = (index+4)%50;
}

--
Jacob Jensen
E-mail: jacob@etlivmedsle.dk
Hjemmeside: www.etlivmedsle.dk



 
 
Ivan Johansen (16-08-2006)
Kommentar
Fra : Ivan Johansen


Dato : 16-08-06 07:55

Jacob Jensen wrote:
> unsigned int fourBytes = 0;
>
> BYTE* writeHere = (BYTE*)writeAddr;
> for(int i=0; i<numBytesToWrite; i+=4)
> {
> fourBytes = wave[index];
> for(int j=1; j<4; j++)
> {
> fourBytes = fourBytes << 8;
> fourBytes += wave[index+j];
> }
> *(writeHere+i) = fourBytes;
> index = (index+4)%50;
> }

Det ser ud til at dit problem er at writeHere er en pointer til BYTE
mens du forsøger at skrive 32 bit til den. Prøv at ændre den til:
DWORD* writeHere = (DWORD*)writeAddr;

Derudover skal din for-løkke kun tælle en op hver gang og kun tælle til
numBytesToWrite/4:
for(int i=0; i<numBytesToWrite/4; i++)

Jeg kender ikke DirectSound, men er det meningen at du vil konvertere
fra big endian til little endian?

Ivan Johansen

Jacob Jensen (16-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 16-08-06 09:54

> Det ser ud til at dit problem er at writeHere er en pointer til BYTE mens
> du forsøger at skrive 32 bit til den. Prøv at ændre den til:
> DWORD* writeHere = (DWORD*)writeAddr;

> Derudover skal din for-løkke kun tælle en op hver gang og kun tælle til
> numBytesToWrite/4:
> for(int i=0; i<numBytesToWrite/4; i++)

Det havde jeg selv overvejet, men jeg kunne ikke se det var et problem. Om
ikke andet så har jeg nu prøvet at ændre det, og der sker nøjagtigt det
samme. Et "klik" i mine højtalere er alt jeg kan høre.

> Jeg kender ikke DirectSound, men er det meningen at du vil konvertere fra
> big endian til little endian?

Det kan jeg ikke tro. Jeg har følgende fra DirectX SDK hjælpen:

1 - Call DirectSoundCreate8 to create an object that supports the
IDirectSound8 interface.
2 - Create a secondary buffer
3 - Obtain PCM data
4 - Put data in the buffer
5 - Play the buffer

....og et andet sted er nr. 4 uddybet (dette er for statiske buffere, ikke
streaming buffere. Men det er fint.)

1 - Lock the entire buffer...
2 - Write the audio data to the returned address by using a standard
memory-copy routine
3 - Unlock the buffer...

Det lyder som om det bare skal kopieres. Spørgsmålet er hvorfor jeg ikke
hører noget. Jeg kunne selvfølgelig sætte mig ind i hvordan jeg kan læse fra
en wav-fil, men det er vist lidt omstændigt, og jeg vil være helt tilfreds
med selv at generere en tone i første omgang.

PS: Ovenstående findes også på MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/dx9_directsound.asp

Jacob



Ivan Johansen (16-08-2006)
Kommentar
Fra : Ivan Johansen


Dato : 16-08-06 21:53

Jacob Jensen wrote:
> Det lyder som om det bare skal kopieres. Spørgsmålet er hvorfor jeg ikke
> hører noget. Jeg kunne selvfølgelig sætte mig ind i hvordan jeg kan læse fra
> en wav-fil, men det er vist lidt omstændigt, og jeg vil være helt tilfreds
> med selv at generere en tone i første omgang.

Jeg er lidt i tvivl om hvad det du præcist forsøger. I din oprindelige
kode kombinerede du 4 bytes til en 32 bit værdi. Er du sikker på at det
er det du vil? Tror du ikke du hellere vil bruge hver byte som en sample
og kopiere den ind i bufferen:
DWORD* writeHere = (DWORD*)writeAddr;
for(int i=0, index=0; i<numBytesToWrite; ++i)
{
writeHere[i] = wave[index];
index = (index+1)%50;
}

Ivan Johansen

Jacob Jensen (16-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 16-08-06 22:15

> Jeg er lidt i tvivl om hvad det du præcist forsøger. I din oprindelige
> kode kombinerede du 4 bytes til en 32 bit værdi. Er du sikker på at det er
> det du vil? Tror du ikke du hellere vil bruge hver byte som en sample og
> kopiere den ind i bufferen:

Jo det var det jeg ville. Var det ikke det jeg gjorde (omend måske på en
lidt besværlig måde)?

> DWORD* writeHere = (DWORD*)writeAddr;
> for(int i=0, index=0; i<numBytesToWrite; ++i)
> {
> writeHere[i] = wave[index];
> index = (index+1)%50;
> }

Det ser pænere ud :) Men nu har jeg kodet en hel wave-indlæser så jeg er fri
for at tænke på om det jeg gjorde faktisk fungerede. Jeg har startet en ny
tråd om dette.

Der kan du også se hele min kode.

Jeg håber virkeligt snart at få det her til at virke.

Jacob



Ivan Johansen (16-08-2006)
Kommentar
Fra : Ivan Johansen


Dato : 16-08-06 22:22

Jacob Jensen wrote:
> PS: Ovenstående findes også på MSDN:
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/dx9_directsound.asp

Jeg har nu kigget lidt i dokumentationen, og jeg tror du bliver nødt til
at kalde IDirectSound8::SetFormat() for at angive at du vil spille PCM i
mono med 8 bit samples. Derefter kan du kopiere dine data direkte:
BYTE* writeHere = (BYTE*)writeAddr;
for(int i=0, index=0; i<numBytesToWrite; ++i)
{
writeHere[i] = wave[index];
index = (index+1)%50;
}

Men det ser ud til at der findes nogle eksempler i SDK'en. Måske du
skulle kigge lidt på dem.

Ivan Johansen

Jacob Jensen (16-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 16-08-06 22:38

> Jeg har nu kigget lidt i dokumentationen, og jeg tror du bliver nødt til
> at kalde IDirectSound8::SetFormat() for at angive at du vil spille PCM i
> mono med 8 bit samples. Derefter kan du kopiere dine data direkte:

Ok. Det kan da godt være. Den sætter vist primary buffer's format.

Der står under SetFormat() i dokumentationen at den skal kaldes inden der
oprettes en buffer. Men hvordan kan jeg så kalde den? Den er defineret som
"virtual HRESULT SetFormat(...)". Har du nogle ideer?

> Men det ser ud til at der findes nogle eksempler i SDK'en. Måske du skulle
> kigge lidt på dem.

Been there. Jeg må jo bare lede og lede. Problemet er at de programmer er en
lille smule mere omfattende end hvad der er nødvendigt for blot at afspille
en lyd uden streaming osv.

Måske skyldes alt det her den advarsel som minGW kommer med under
oversættelse. Se evt. tråden "
Fejl ved oversættelse - DirectX og MinGW".

Mange tak for din indsats.

Jacob



Ivan Johansen (16-08-2006)
Kommentar
Fra : Ivan Johansen


Dato : 16-08-06 23:14

Jacob Jensen wrote:
> Ok. Det kan da godt være. Den sætter vist primary buffer's format.

Ja, det ser godt nok sådan ud. Jeg er ikke klar over hvad forskellen på
primary og secondary buffer er. Men jeg kan se at formatet bliver sat
når man opretter en buffer, så det burde være godt nok.

Ivan Johansen



Jacob Jensen (17-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 17-08-06 06:16

> Ja, det ser godt nok sådan ud. Jeg er ikke klar over hvad forskellen på
> primary og secondary buffer er. Men jeg kan se at formatet bliver sat når
> man opretter en buffer, så det burde være godt nok.

Så vidt jeg ved (og jeg er nybegynder her) så er der én primary buffer og
det er den hvor alle lyde bliver mixet til. Programmer (også flere
forskellige programmer) kan så have sekundære buffers.

Det DirectSound så gør er vist at mixe alle de sekundære buffer'e der er ved
at blive afspillet til primary buffer. Men jeg er ikke helt sikker. Og jeg
har så inden anelse om hvordan den vil mixe nogle ting der ikke "passer
sammen".

Jacob



Søg
Reklame
Statistik
Spørgsmål : 177428
Tips : 31962
Nyheder : 719565
Indlæg : 6407943
Brugere : 218877

Månedens bedste
Årets bedste
Sidste års bedste