Sound
-
Hallo!
Hab nen Problem mit DSOund. MeinProggi stürzt immer ab. Ich hab mal irgendwo gelesen, dass man eigentlich auch die API.Funktionen für WAV-Play benutzen kann. Sollte man das tun, oder kann das weniger als DirectSoun/Audio? Oder spricht etwas anderes dagegen? Und wenn nicht: Wie heißen denndann die Funktionen der WinAPI?
Gruß, Maxi
-
Hi !
Poste mal was Code, dann können wir dir auch mit dem Absturz helfen.
Die Funktion die du wohl meinst heißt PlaySound, ist in der winmm.lib enthalten && Teil der Winapi.
Warum du es nicht verwenden solltest :- lahm (was sonst)
- nur ein Sound gleichzeitig abspielbar
-
Bin gard nich zuhause. Aber ich kann schnonmal sagen, dass ich den Code aus dem GameCore aus dem Buch "Programming Role Playing Games with DirectX" (Wie oft hab ich den Titel schon geschriebn??) benutze. Immer wenn da nen Sound abgespielt wird, entsteht ein BleuScreen: Der schwere AusnahmeFehler... die Anwendung kann gegegenenfalls normal fortgesetzt werden...
glaub ich , jedenfalls, kann den Screen nicht am BiboComputer nachahmen..
-
Mh.. starte mal dxdiag und lass den DX Soundcheck drüberlaufen !
-
So, nach langer Zeit mache gebe ich jetzt endlich den Code aus:
DxDiag findet keinen Fehler bei DirectSound. Alles leif Fehler frei, er sagte nur, dass ich keinen Hardwarepuffer habe zum Abspielen. So hier nun der Code:
Is t aus dem Gamecore entnommen von Programming Role Playing Games with DirectX:
Ich hab iauch überhaupt keine Azhnung von DSound, leider.m_Sound.Init(this->GethWnd()) // hier der Aufruf der InitFunktion // hier die Init-Funktion: BOOL cSound::Init(HWND hWnd, long Frequency, short Channels, short BitsPerSample, long CooperativeLevel) { CHAR strPath[MAX_PATH]; WCHAR wstrSearchPath[MAX_PATH]; DSBUFFERDESC dsbd; WAVEFORMATEX wfex; long VolumeLevel; short i; // Shutdown system in case of prior install Shutdown(); // Save parent window handle if((m_hWnd = hWnd) == NULL) return FALSE; /////////////////////////////////////////////////////////////////// // Initialize DirectSound /////////////////////////////////////////////////////////////////// // Save settings of sound setup if(CooperativeLevel == DSSCL_NORMAL) CooperativeLevel = DSSCL_PRIORITY; m_CooperativeLevel = CooperativeLevel; m_Frequency = Frequency; m_Channels = Channels; m_BitsPerSample = BitsPerSample; // create an IDirectSound8 object if(FAILED(DirectSoundCreate8(NULL, &m_pDS, NULL))) return FALSE; // Set cooperative mode if(FAILED(m_pDS->SetCooperativeLevel(m_hWnd, m_CooperativeLevel))) return FALSE; // Get primary buffer control ZeroMemory(&dsbd, sizeof(DSBUFFERDESC)); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME; dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = NULL; if(FAILED(m_pDS->CreateSoundBuffer(&dsbd, &m_pDSBPrimary, NULL))) return FALSE; // Set the primary buffer format ZeroMemory(&wfex, sizeof(WAVEFORMATEX)); wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = (WORD)m_Channels; wfex.nSamplesPerSec = m_Frequency; wfex.wBitsPerSample = (WORD)m_BitsPerSample; wfex.nBlockAlign = wfex.wBitsPerSample / 8 * wfex.nChannels; wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; if(FAILED(m_pDSBPrimary->SetFormat(&wfex))) return FALSE; // Create the events, plus // an extra one for thread termination for(i=0;i<33;i++) { if((m_Events[i] = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL) return FALSE; } // Create a thread for handling notifications if((m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HandleNotifications, (LPVOID)this, 0, &m_ThreadID)) == NULL) return FALSE; // Start main buffer playing if(FAILED(m_pDSBPrimary->Play(0, 0, DSBPLAY_LOOPING))) return FALSE; /////////////////////////////////////////////////////////////////// // Initialize DirectMusic /////////////////////////////////////////////////////////////////// // Create the DirectMusic loader object CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, IID_IDirectMusicLoader8, (void**)&m_pDMLoader); // Create the DirectMusic performance object CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, IID_IDirectMusicPerformance8, (void**)&m_pDMPerformance); // Initialize the performance with the standard audio path. // This initializes both DirectMusic and DirectSound and // sets up the synthesizer. m_pDMPerformance->InitAudio(NULL, NULL, m_hWnd, DMUS_APATH_SHARED_STEREOPLUSREVERB, 128, DMUS_AUDIOF_ALL, NULL); // set the performance global volume to +10 decibels VolumeLevel = 1000; if(FAILED(m_pDMPerformance->SetGlobalParam(GUID_PerfMasterVolume, &VolumeLevel, sizeof(long)))) return FALSE; // Tell DirectMusic where the default search path is GetCurrentDirectory(MAX_PATH, strPath); MultiByteToWideChar(CP_ACP, 0, strPath, -1, wstrSearchPath, MAX_PATH); m_pDMLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wstrSearchPath, FALSE); // Set default volume to full SetVolume(100); return TRUE; } // Dann das Laden der SoundDatei: m_Klang.LoadWAV("roar.wav") // dEr aufruf (m_Klang ist ein Objekt von Typ cSoundData hier die Funktion: BOOL cSoundData::LoadWAV(char *Filename, FILE *fp) { if(LoadWAVHeader(Filename, fp) == FALSE) // Bei LoadWavHeader entsteht kein Fheler, deswegen lass ich es so, shreib es hier nich hin return FALSE; if(Create() == FALSE) return FALSE; // open file, seek to position and read in data if(Filename != NULL) { if((fp=fopen(Filename, "rb"))==NULL) return FALSE; } fseek(fp, m_StartPos, SEEK_SET); fread(m_Buf, 1, m_Size, fp); m_StartPos = m_Pos = 0; // close up file if(Filename != NULL) fclose(fp); return TRUE; } // Dann kommt noch m_Channel.Create(&m_Sound, &m_Klang); // der Aufruf // hier die Funktion: BOOL cSoundChannel::Create(cSound *Sound, cSoundData *SoundDesc) { return Create(Sound, SoundDesc->m_Frequency, SoundDesc->m_Channels, SoundDesc->m_BitsPerSample); } // und ann hier Create BOOL cSoundChannel::Create(cSound *Sound, long Frequency, short Channels, short BitsPerSample) { DSBUFFERDESC dsbd; WAVEFORMATEX wfex; HANDLE hEvent; DSBPOSITIONNOTIFY dspn[3]; IDirectSoundBuffer *pDSBuffer; // Free a prior channel Free(); if((m_Sound = Sound) == NULL) return FALSE; if(m_Sound->GetDirectSoundCOM() == NULL) return FALSE; // Save playback format m_Frequency = Frequency; m_BitsPerSample = BitsPerSample; m_Channels = Channels; // Create a new sound buffer for this channel // Using specified format ZeroMemory(&wfex, sizeof(WAVEFORMATEX)); wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = (WORD)m_Channels; wfex.nSamplesPerSec = m_Frequency; wfex.wBitsPerSample = (WORD)m_BitsPerSample; wfex.nBlockAlign = wfex.wBitsPerSample / 8 * wfex.nChannels; wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; ZeroMemory(&dsbd, sizeof(DSBUFFERDESC)); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE; dsbd.dwBufferBytes = g_SoundBufferSize; dsbd.lpwfxFormat = &wfex; if(FAILED(m_Sound->GetDirectSoundCOM()->CreateSoundBuffer(&dsbd, &pDSBuffer, NULL))) return FALSE; // query for newer interface if(FAILED(pDSBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&m_pDSBuffer))) { pDSBuffer->Release(); return FALSE; } // Release old object - we have the newer one now pDSBuffer->Release(); // Create the notification interface if(FAILED(m_pDSBuffer->QueryInterface(IID_IDirectSoundNotify8, (void**)&m_pDSNotify))) return FALSE; // Get an event for this if(m_Sound->AssignEvent(this, &m_Event, &hEvent) == FALSE) return FALSE; // Setup the 4 notification positions dspn[0].dwOffset = g_SoundBufferChunk - 1; dspn[0].hEventNotify = hEvent; dspn[1].dwOffset = g_SoundBufferChunk * 2 - 1; dspn[1].hEventNotify = hEvent; dspn[2].dwOffset = g_SoundBufferChunk * 3 - 1; dspn[2].hEventNotify = hEvent; dspn[3].dwOffset = g_SoundBufferSize - 1; dspn[3].hEventNotify = hEvent; if(FAILED(m_pDSNotify->SetNotificationPositions(4, dspn))) return FALSE; // set the pan and default volume SetVolume(100); SetPan(0); return TRUE; } // bei obiger Funktion entsteht auch kein Fheler. // So, und dann hier ddie Fehlerfunktion, denke ich: m_Channel.Play(&m_Klang, 1); // der aufruf //hier die function: BOOL cSoundChannel::Play(cSoundData *Desc, long VolumePercent, long Loop) { if(Desc == NULL) return FALSE; if(m_pDSBuffer == NULL) return FALSE; if(m_pDSNotify == NULL) return FALSE; // Stop any playback Stop(); // Restore a lost buffer just in case m_pDSBuffer->Restore(); // Setup playing information m_Desc.Copy(Desc); // Set looping data m_Loop = Loop; // Calculate stop section position if(!m_Loop) m_StopSection = -1; else m_StopSection = (short)(((m_Desc.m_Size * m_Loop) % g_SoundBufferSize) / g_SoundBufferChunk); // Buffer in data m_LoadSection = 0; BufferData(); BufferData(); BufferData(); BufferData(); // Set the volume SetVolume(VolumePercent); // Set position and begin play m_NextNotify = 0; if(FAILED(m_pDSBuffer->SetCurrentPosition(0))) return FALSE; if(FAILED(m_pDSBuffer->Play(0,0,DSBPLAY_LOOPING))) return FALSE; // Flag as playing m_Playing = TRUE; return TRUE; } Sie gibt auch keinen Fehler zurück. Man hört auch bein Abspeilen den Sound, nur, danach kommt ien BlueScreen Der ausnahmefehler... kann gegebnenfallss normal fortgesetzt werden.
Ich, weiß, amich kotzt das auch immer an, wenn jemand so viel code psotet und dann muss jemand den Fheler suchen. Nur, ich kann ihn nich kürzen, weil ich nich weiß, wo der Fehler liegt, weil mein DirectX im Arbeitsspeicher oder sonstwo sich dann immer aufhängt. undadann muss ich neutstarten.
Ich hoff ihr könnt mir helfen.Gru, Maxi
[ Dieser Beitrag wurde am 09.03.2003 um 10:26 Uhr von Maxi editiert. ]
-
Mensch Leute, kann mir denn hier kein Fachmann helfen? Alleine krieg ich das eifach nich hin. Oder schlagt mir ne andere Möglichkeit vor, bitte. Das ist mein erstes DX-Projekt, Pong, und da muss eben auch nnen bisschen sound mit rein.
Gruß, Maxi
-
Original erstellt von <Maxi>:
Oder schlagt mir ne andere Möglichkeit vor, bitte.FMod
-
Was ist FMod?
-
Das ist 'ne Sound library.
-
-
Hast du den Soundcheck mal drüberlaufen lassen ?
-
Nur, ich kann ihn nich kürzen, weil ich nich weiß, wo der Fehler liegt, weil mein DirectX im Arbeitsspeicher oder sonstwo sich dann immer aufhängt. undadann muss ich neutstarten.
Benutzt Du zufällig Win 98 oder ME?
-
Ja, Windows 98, auf nem Media-Markt-PC. 500MHz, 128MB-Ram, Sound On-Board.
Warum , weißt du wo der Fehler leigen könnte??
Grüße der Hoffung
, Maxi
-
Warum , weißt du wo der Fehler leigen könnte??
Nein.
Aber zu Deinem Neustart-Problem:
Wenn ich mich recht entsinne, gab Microsoft mal das Problem bekannt, daß wenn DirectX Applikationen unter Windows 98 oder Windows ME abstürzen, meistens ein Neustart vonnöten ist, um weitere DirectX-Appz laufen zu lassen, anders als bei Windows-Systemen mit NT-Kernel.
Problem war glaub' ich immer ein aufgehängter DDHELP-Thread oder so...
Zumindest alte DirectX-Versionen hatten dafür immer eine KillHelp.EXE oder so rumfliegen. Kannst ja mal gucken, ob Du was entsprechendes findest, dann mußt Du nach jedem Test nicht immer'n Reboot machen...CU, Sarge
-
Und neueste Treiber hast Du auch mal probiert, nicht, daß es an sowas liegt...!?
Wofür dient eigentlich das Shutdown() in der Init()-Methode?!? Irgendwie seltsame Konstellation...
MfG, Sarge
-
Nach den Treibern kann ich jetzt nicht gucken, bin grad nicht zuhause. Und wo kann ich denn mein Main-Board-Typ herausfinden?
Ich glaub das Shutdown dient dazu, erstmal alles zu leeren, falls die Init()-Funktion mehrmals aufgerufen wird.
Und die Killhelop muss ich dann einfach ausführen, ja? Das ist son komischer Dateiname, hört sich nicht so harmlos an.
Gruß, Maxi
-
Mainboard: Nun, entweder aufschrauben -> nachgucken.
Oder mit so System-Tools. Sandra oder so...Jau, in meinem DirextX 6.1 SDK liegt sie unter \bin\DXUtils.
KillHelp.exe - einfach ausführen. Die killt halt den DDHELP Thread. Nur für Windows9X - Systeme interessant.Bei DirectX 9 kann ich was entsprechendes nicht finden. Ggf. bei microsoft.com vorbeisurfen...
MfG, Sarge
P.S.:
Das ist son komischer Dateiname, hört sich nicht so harmlos an.
Dann nenn' sie halt um in "Ich-bin-lieb.exe" oder "Klezhammer.exe" oder so...