Toon posts:

[C/C++] waveOutOpen resource already allocated

Pagina: 1
Acties:

Verwijderd

Topicstarter
Op dit moment ben ik bezig met het schrijven van een basis player / recorder van wave bestanden. Met mogelijkheden om uit te breiden met een equaliser. Een om wave bestand te spelen gebruik ik de waveOutOpen functie op de volgende manier:
C++:
1
mmErr = waveOutOpen(&hWave, WAVE_MAPPER, &waveformat, (DWORD) waveOutProc, NULL, CALLBACK_FUNCTION);


De functie waar dit in staat wordt hier in regel 13 aangeroepen:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void CSEBaseDlg::OnOpenfile() 
{
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | FN_OVERWRITEPROMPT, "All|*.*|wave|*.wav||");
if (dlg.DoModal() == IDOK)
{
      pathname = dlg.GetPathName();
      file = new CFile;
      file->Open(pathname, NULL, NULL);
      m_PlayButton.EnableWindow(true);
}
m_OpenedFile = file->GetFileName();
SetDlgItemText(IDC_OPENEDFILE, m_OpenedFile);
player.PlayOpen();
player.LoadWave(file);
}


Wanneer ik een wave file probeer te openen retourneerd deze functie MMSYSERR_ALLOCATED. In de MSDN staat daarbij dat de resource is already allocated. Alle voorbeeldcode die ik heb gevonden gebruikt deze functie op precies dezelfde manier, dus snap ik niet wat er mis mee is.

Daarna heb ik gekeken of er wel een device aanwezig was dat WAVE support heeft met de waveOutGetNumDevs() functie. Daaruit blijkt dat er 1 device aanwezig is.
Als ik een wave file probeer af et spelen met de sndPlaySound() functie werkt het perfect, dus op een of andere manier gaat het openen dus niet goed.

Heeft iemand een idee waar de fout ligt?

Bij voorbaat dank,

Miep.

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 30-07 16:33
Weet je zeker dat geen andere app de geluidskaart gebruikt (als je niet met 2000 of XP werkt)?

Verder ziet het er goed uit. De code hierna is hoe ik waveOutOpen() aanroep en dat werkt bij mij goed:

C:
1
2
3
4
5
6
7
8
9
10
11
12
    HWAVEOUT waveout_handle;
    WAVEFORMATEX wf;

    wf.cbSize = sizeof(wf);
    wf.wFormatTag = WAVE_FORMAT_PCM;
    wf.nChannels = WF_CHANNELS;
    wf.nSamplesPerSec = WF_SAMPLINGRATE;
    wf.wBitsPerSample = WF_BYTESPERSAMPLE * 8;
    wf.nBlockAlign = wf.nChannels * WF_BYTESPERSAMPLE;
    wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec;

    check_mm_error("waveOutOpen", waveOutOpen(&waveout_handle, WAVE_MAPPER, &wf, (DWORD)GetCurrentThreadId(), 0, CALLBACK_THREAD | WAVE_FORMAT_DIRECT | WAVE_ALLOWSYNC));

met de functie check_mm_error() als volgt:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
void check_mm_error(const char *func_name, MMRESULT result) {
    char buf[MAXERRORLENGTH];

    printf("%s: ", func_name);

    if(result!=MMSYSERR_NOERROR) {
        waveInGetErrorText(result, &buf[0], MAXERRORLENGTH);
        printf("%s\n", buf);
        exit(1);
    } else {
        printf("ok\n");
    }
}

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Je hebt met 99.99% waarschijnlijkheid Winamp, Windows Media Player oid open staan.

Professionele website nodig?


Verwijderd

Topicstarter
Ik werk onder Windows 2000, en ik heb absoluut geen mediaplayer of winamp aanstaan. Wat ik vooral heel vreemd vindt is dat als ik de sndPlaySound functie gebruik het wel werkt.

Ik stuur het dadelijk naar iemand met Windows XP en die zal testen of het daar wel werkt.

[ Voor 21% gewijzigd door Verwijderd op 19-03-2003 09:32 ]


  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
kan je iets meer laten zien van de code waar
code:
1
mmErr = waveOutOpen(&hWave, WAVE_MAPPER, &waveformat, (DWORD) waveOutProc, NULL, CALLBACK_FUNCTION);

staat ?

Verwijderd

Topicstarter
TijnFLiP schreef op 19 March 2003 @ 09:31:
kan je iets meer laten zien van de code waar
code:
1
mmErr = waveOutOpen(&hWave, WAVE_MAPPER, &waveformat, (DWORD) waveOutProc, NULL, CALLBACK_FUNCTION);

staat ?
Om die code staat niet zo heel veel:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool SEPlayer::PlayOpen()
{
    mmErr = waveOutOpen(&hWave, WAVE_MAPPER, &waveformat, (DWORD) waveOutProc, NULL, CALLBACK_FUNCTION);
    if(mmErr != MMSYSERR_NOERROR)
    {
        if(mmErr = MMSYSERR_ALLOCATED)
        {
            AfxMessageBox("Resource already allocated");
        }
        else
        {
            AfxMessageBox("Another error occurred");
        }
        return false;
    }
}


Dat ids de functie. Ik gok dat je dit niet precies bedoelt, maar bijvoorbeeld een of andere initialisatie?

  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
Hoe maak je bijv. waveformat aan?

Verwijderd

Topicstarter
De waveformat structure wordt aangemaakt in de volgende functie:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void SEPlayer::LoadWave(CFile * file)
{
    WAVEFORMATEX wavetex;
    char temp[10];
    DWORD dwFileSize;
    DWORD dwNum;
    DWORD dwFmtSize;
    ZeroMemory(temp, 10 * sizeof(char));
    file->Read(temp, 4 * sizeof(char));
    file->Read(&dwFileSize, sizeof(dwFileSize));
    file->Read(temp, 8 * sizeof(char));
    file->Read(&dwFmtSize, sizeof(dwFmtSize));
    file->Read(&wavetex.wFormatTag, sizeof(wavetex.wFormatTag));
    file->Read(&wavetex.nChannels, sizeof(wavetex.nChannels));
    file->Read(&wavetex.nSamplesPerSec, sizeof(wavetex.nSamplesPerSec));
    file->Read(&wavetex.nAvgBytesPerSec, sizeof(wavetex.nAvgBytesPerSec));
    file->Read(&wavetex.nBlockAlign, sizeof(wavetex.nBlockAlign));
    file->Read(&wavetex.wBitsPerSample, sizeof(wavetex.wBitsPerSample));
    ZeroMemory(temp, 10 * sizeof(char));
    file->Read(temp, 4 * sizeof(char));
    file->Read(&dwNum, sizeof(dwNum));
    buffer.SetNumSamples(dwNum / waveformat.nBlockAlign, waveformat.nBlockAlign);
    file->Read(buffer.GetBuffer(), dwNum);
    waveformat = wavetex;
}


hierin is wavetex de locale, en waveformat de globale variabele die voor de rest gebruikt wordt

-EDIT-
Onder Windows XP werkt het programma ook niet.

[ Voor 12% gewijzigd door Verwijderd op 19-03-2003 10:26 ]


  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
kan zijn dat ik er overheen lees maar ik mis
code:
1
wavetex.cbSize = sizeof(wavetex);


Kijk anders eens hoe MatthijsLn dat heeft gedaan

Verwijderd

Topicstarter
Ok dan, ik heb even nagedacht en geexpirimenteerd. Ik heb nu twee dingen veranderd:
- Ik heb inderdaad die cbSize toegevoegd:
C:
1
2
 file->Read(&wavetex.cbSize, sizeof(wavetex.cbSize));
 


- Ik heb de twee functie aanroepen van laden wave file en openen wave device omgedraaid:
C:
1
2
3
 player.LoadWave(file);
 player.PlayOpen();
 


Maar nog steeds krijg ik die error dat de resource already allocated is.

  • AFR
  • Registratie: Juni 2001
  • Niet online

AFR

Weet je zeker dat je te maken hebt met een MMSYSERR_ALLOCATED exception?
In je code voor de fout afhandeling gebruik je immers een toekenning (=) in plaats van een vergelijking (==): mmErr = MMSYSERR_ALLOCATED

Verwijderd

Topicstarter
Als ik dat doe, dan ik krijg ik bij iedere foutmelding die ik uitprobeer (genoemd in MSDN) "Another error ocurred".

Als ik de tekst van de error bekijk via de waveOutGetErrorText zegt:

Error = Er is een ongeldige parameter doorgegeven aan een systeemfunctie.

  • Lone Gunman
  • Registratie: Juni 1999
  • Niet online
is de callback functie waveOutProc een member van de SEPlayer class ? als dat zo is moet deze namelijk static zijn. dus static void CALLBACK waveOutProc(.....) in je header en void CALLBACK SEPlayer::waveOutProc(....) in je cpp.

wat AFR al melde, = moet == zijn, als je een toekenning doet zal dat namelijk als true aangezien worden.

[ Voor 23% gewijzigd door Lone Gunman op 20-03-2003 00:42 ]

Experience has taught me that interest begets expectation, and expectation begets disappointment, so the key to avoiding disappointment is to avoid interest.


  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 30-07 16:33
Verwijderd schreef op 19 March 2003 @ 20:17:
Ok dan, ik heb even nagedacht en geexpirimenteerd. Ik heb nu twee dingen veranderd:
- Ik heb inderdaad die cbSize toegevoegd:
C:
1
2
 file->Read(&wavetex.cbSize, sizeof(wavetex.cbSize));
 
Dat klopt niet; dat moet als volgt:
C:
1
wavetex.cbSize = sizeof(wavetex);


En wat zijn de waardes de je uit de file leest? Het lijkt me zowieso onverstandig om die WAVEFORMATEX struct direct uit een file te lezen zonder enige checking of de waardes wel goed zijn; want ik heb zo het idee dat je nu je struct met ongeldige waardes vult.

Daarnaast zou ik eerst beginnen met het afspelen van raw audio samples (converteer een .wav met bv Goldwave naar .raw, 16 bit little endian stereo 44100 Hz).

Dan kan je je WAVEFORMATEX struct als volgt vullen:
C:
1
2
3
4
5
6
7
8
9
10
11
#define WF_CHANNELS 2
#define WF_SAMPLINGRATE 44100
#define WF_BYTESPERSAMPLE 2

wf.cbSize = sizeof(wf); 
wf.wFormatTag = WAVE_FORMAT_PCM; 
wf.nChannels = WF_CHANNELS; 
wf.nSamplesPerSec = WF_SAMPLINGRATE; 
wf.wBitsPerSample = WF_BYTESPERSAMPLE * 8; 
wf.nBlockAlign = wf.nChannels * WF_BYTESPERSAMPLE; 
wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec; 

Bij de laatste parameter van waveOutOpen() dan ook WAVE_FORMAT_DIRECT geven. Daarna kan je met waveOutWrite() direct je raw samples uit de .raw file afspelen.

Verwijderd

Topicstarter
Ok, inmiddels weer op Windows 2000 krijg ik een ander error string:

The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats.

Dus kijk ik naar de capabilities functie van mciSendString. Die kan ik dus alleen maar gebruiken als ik een device geopend heb.

Ik open een gewoon wave filetje???

De informatie die gelezen wordt uit de file heb ik gecontroleerd met traces en die info klopt gewoon, 44100 Hz, 2 kanaals en 8 bits per sample.

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 30-07 16:33
Verwijderd schreef op 20 maart 2003 @ 10:46:
The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats.
...
Ik open een gewoon wave filetje???

De informatie die gelezen wordt uit de file heb ik gecontroleerd met traces en die info klopt gewoon, 44100 Hz, 2 kanaals en 8 bits per sample.
Als je wave file niet gecomprimeerde samples bevat maar alleen PCM, dan moet WAVEFORMATEX.wFormatTag de waarde WAVE_FORMAT_PCM hebben en bij de laatste parameter van waveOutOpen() moet je dan WAVE_FORMAT_DIRECT geven.
Pagina: 1