Tonerzeugung



  • Ahhh ok, ja das klingt einleuchtend.
    Und dann sollte schon ein Ton heraus kommen?



  • Patrick1990 schrieb:

    Ahhh ok, ja das klingt einleuchtend.
    Und dann sollte schon ein Ton heraus kommen?

    probiers doch einfach 😉



  • Ok, ich bekomme folgende Mitteilung:

    http://fs1.directupload.net/images/150507/temp/rtngsoin.png

    Scheinbar ist das unter Parallels Desktop nicht möglich.



  • Steht doch eh da was (vermutlich) das Problem ist.
    Stell dein Projekt auf Win32 um und probier es nochmal.



  • Wenn ich das unter Project --> Properties ändere erscheinen mir mehrere Fehlermeldungen:

    1>------ Build started: Project: A2_Tonerzeugung, Configuration: Debug Win32 ------
    1>Tonerzeugung.obj : error LNK2019: unresolved external symbol "unsigned long __stdcall GetDllStatus(void)" (?GetDllStatus@@YGKXZ) referenced in function _main
    1>Tonerzeugung.obj : error LNK2019: unresolved external symbol "int __stdcall InitializeOls(void)" (?InitializeOls@@YGHXZ) referenced in function _main
    1>Tonerzeugung.obj : error LNK2019: unresolved external symbol "void __stdcall DeinitializeOls(void)" (?DeinitializeOls@@YGXXZ) referenced in function _main
    1>Tonerzeugung.obj : error LNK2019: unresolved external symbol "void __stdcall WriteIoPortByte(unsigned short,unsigned char)" (?WriteIoPortByte@@YGXGE@Z) referenced in function _main
    1>\\psf\Home\Desktop\A2_Tonerzeugung\Debug\A2_Tonerzeugung.exe : fatal error LNK1120: 4 unresolved externals
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    

    Vielleicht sollte ich besser ein 64-Bit Betriebssystem aufspielen?



  • Du mußt dem Linker noch die Library (.lib-Datei) zu der "OlsApi.h" mitgeben (+ evtl. noch die Linkerpfade anpassen).



  • Oha davon habe ich keine Ahnung. Wie geht sowas?



  • Projekteigenschaften, Linker, Eingabe bzw. Input, und dann den Pfad zur LIB angeben.

    Siehe auch Internet, hier erster Treffer auf stackoverflow:

    http://stackoverflow.com/questions/20058864/how-to-include-libraries-in-visual-studio-2012



  • Das sieht aus als wolltest Du über den PC-Speaker Sound ausgeben.
    Da kann man aus dem alten Buch PC-Intern von Michael Tischler (DATA-BECKER)
    dessen Interuptierende Sprachausgabe betrachten.

    Unter Windows kannst Du zb. einen Text sprechen lassen wie folg:

    PseudoCode:

    #include <sphelper.h>
    static unsigned __stdcall ClientSay(void *ptr)
    {
    	CString str((char *)ptr);
    	if (FAILED(::CoInitialize(NULL)))return 0;
    	CComPtr<ISpVoice>              cpVoice;
    	CComPtr<ISpObjectToken>        cpVoiceToken;
    	CComPtr<IEnumSpObjectTokens>   cpEnum;
    	ULONG                          ulCount(0);
    	if (FAILED(cpVoice.CoCreateInstance(CLSID_SpVoice)))return 0;
    	if (FAILED(SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum)))return 0;
    	if (FAILED(cpEnum->GetCount(&ulCount)))return 0;
    	cpVoiceToken.Release();
    	if (FAILED(cpEnum->Next(1, &cpVoiceToken, NULL)))return 0;
    	if (FAILED(cpVoice->SetVoice(cpVoiceToken)))return 0;
    	cpVoice->Speak(str.AllocSysString(), SPF_ASYNC, NULL);
    	while (cpVoice->WaitUntilDone(33) == S_FALSE);
    	::CoUninitialize();
    	return 0;
    }
    

    Ansonnsten kannst Du alle Frequenzen über die AudioHardware ausgeben:

    CAudioFreqGen::CAudioFreqGen(void)
    {
    	uDeviceID           = WAVE_MAPPER;
    	pwfx                = NULL;
    	dwCallback          = NULL;
    	dwCallbackInstance  = NULL;
    	fdwOpen             = CALLBACK_NULL;
    	unsigned char *buf  = NULL;
    	m_lastfrq           = 0;
        ghwo                = 0;              
    	PrepareDevice();
    }
    
    CAudioFreqGen::~CAudioFreqGen(void)
    {
    	CloseDevice();
    }
    
    char *CAudioFreqGen::PrepareDevice(void)
    {
     pwfx=new WAVEFORMATEX;
     pwfx->wFormatTag=WAVE_FORMAT_PCM;
     pwfx->nChannels=1;
     pwfx->nSamplesPerSec=SPS;
     pwfx->nAvgBytesPerSec=SPS;
     pwfx->nBlockAlign=1;
     pwfx->wBitsPerSample=8;
     mmres=waveOutOpen(&ghwo,uDeviceID,pwfx,dwCallback,dwCallbackInstance,fdwOpen);
     delete pwfx;
     if(mmres != MMSYSERR_NOERROR)
     {
      return "Cant open device.";
     }
     buf=new unsigned char[SPS];
     if(buf == NULL)
     {
      CloseDevice();
      return "Cant allocate memory.";
     }
     memset(buf,0,SPS);
     pwh.lpData=(LPSTR)buf;
     pwh.dwBufferLength=SPS;
     pwh.dwFlags=WHDR_BEGINLOOP;
     pwh.dwLoops=1;
     mmres = waveOutPrepareHeader(ghwo,&pwh,sizeof(pwh));
     pwh.dwFlags=WHDR_BEGINLOOP|WHDR_ENDLOOP|WHDR_PREPARED;
     pwh.dwLoops=0xFFFFFFFF;                // Number of loops == about 136 years:)
     if(mmres != MMSYSERR_NOERROR)
     {
      CloseDevice();
      return "Device prepare error.";
     }
    
     return NULL;
    }
    
    //---------------------------------------------------------------------------
    
    char *CAudioFreqGen::CloseDevice(void)
    {
     if(buf) delete [] buf;
    
     if(ghwo)
     {
    	mmres=waveOutReset(ghwo);
    	if(mmres != MMSYSERR_NOERROR)
    	return "Cant close device.";
    	mmres=waveOutClose(ghwo);
    	if(mmres != MMSYSERR_NOERROR)
    	return "Cant close device.";
    
    	ghwo = 0;
     }
    
     return NULL;
    }
    
    //---------------------------------------------------------------------------
    void CAudioFreqGen::Generate(int freq,char amp,float phase)
    {
     if(ghwo)
      if(m_lastfrq != freq)
      {
    	m_lastfrq = freq;
    	char tmp[SPS];
    	register float x=freq*2*3.1416/SPS;
    	for(int cnt=0;cnt<SPS;cnt++)
    	 tmp[cnt]=(unsigned char)(cos(phase+cnt*x)*amp+127);
    	memcpy(&buf[0],&tmp[0],SPS);
      }
    }
    

    Grüße und Erfolg
    Karsten



  • Ich habe nun noch einmal ein 64-Bit Windows als virtuelle Maschine laufen. Nun läuft das Programm, jedoch gibt er aus: Rueckgabewert=5. Er müsste eigentlich ja 0 sein.


Anmelden zum Antworten