Avatar billede Swift Praktikant
19. april 2002 - 12:40 Der er 7 kommentarer og
1 løsning

Simpel lyd i Visual C++ ??

Kan man ikke lave noget MEGET simpelt lyd i C++ ??

Jeg har et array med nogle værdier der skal afspilles. Det array vil jeg så "afspille" enten en enkelt gang eller fx. 1000.

Jeg forestiller mig noget i regningen:

arrayMedLyd = { 0, 0.5, 1, 0.5, 0, -0.5, -1, -0,5 }; //Simpel sinus

for( int i = 0; i < 10000; i++) //Vi afspiller den samme sinus i et stykke tid.
{ afspilLydFunktion( arrayMedLyd, samplingsfrekvens ); }


Kan man lave noget i den stil ??
Jeg vil gerne være fri for WAVEFORMATEX m.v.
Avatar billede kamikaze Nybegynder
19. april 2002 - 13:42 #1
Det eneste "simple" lyd-generering med sinus-toner jeg kender til er fra "Programming Windows 5.ed" af Charles Petzold. Der er en sample:

/*------------------------------------------------------
  SINEWAVE.C -- Multimedia Windows Sine Wave Generator
                (c) Charles Petzold, 1998
  ------------------------------------------------------*/

#include <windows.h>
#include <math.h>
#include "resource.h"

#define SAMPLE_RATE    11025
#define FREQ_MIN          20
#define FREQ_MAX        5000
#define FREQ_INIT        440
#define OUT_BUFFER_SIZE  4096
#define PI                  3.14159

BOOL CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM) ;

TCHAR szAppName [] = TEXT ("SineWave") ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
    if (-1 == DialogBox (hInstance, szAppName, NULL, DlgProc))
    {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
    }
    return 0 ;
}

VOID FillBuffer (PBYTE pBuffer, int iFreq)
{
    static double fAngle ;
    int          i ;

    for (i = 0 ; i < OUT_BUFFER_SIZE ; i++)
    {
          pBuffer [i] = (BYTE) (127 + 127 * sin (fAngle)) ;

          fAngle += 2 * PI * iFreq / SAMPLE_RATE ;

          if (fAngle > 2 * PI)
              fAngle -= 2 * PI ;
    }
}

BOOL CALLBACK DlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static BOOL        bShutOff, bClosing ;
    static HWAVEOUT    hWaveOut ;
    static HWND        hwndScroll ;
    static int          iFreq = FREQ_INIT ;
    static PBYTE        pBuffer1, pBuffer2 ;
    static PWAVEHDR    pWaveHdr1, pWaveHdr2 ;
    static WAVEFORMATEX waveformat ;
    int                iDummy ;
   
    switch (message)
    {
    case WM_INITDIALOG:
          hwndScroll = GetDlgItem (hwnd, IDC_SCROLL) ;
          SetScrollRange (hwndScroll, SB_CTL, FREQ_MIN, FREQ_MAX, FALSE) ;
          SetScrollPos  (hwndScroll, SB_CTL, FREQ_INIT, TRUE) ;
          SetDlgItemInt  (hwnd, IDC_TEXT, FREQ_INIT, FALSE) ;
         
          return TRUE ;
         
    case WM_HSCROLL:
          switch (LOWORD (wParam))
          {
          case SB_LINELEFT:  iFreq -=  1 ;  break ;
          case SB_LINERIGHT:  iFreq +=  1 ;  break ;
          case SB_PAGELEFT:  iFreq /=  2 ;  break ;
          case SB_PAGERIGHT:  iFreq *=  2 ;  break ;
             
          case SB_THUMBTRACK:
              iFreq = HIWORD (wParam) ;
              break ;
             
          case SB_TOP:
              GetScrollRange (hwndScroll, SB_CTL, &iFreq, &iDummy) ;
              break ;
             
          case SB_BOTTOM:
              GetScrollRange (hwndScroll, SB_CTL, &iDummy, &iFreq) ;
              break ;
          }
         
          iFreq = max (FREQ_MIN, min (FREQ_MAX, iFreq)) ;
         
          SetScrollPos (hwndScroll, SB_CTL, iFreq, TRUE) ;
          SetDlgItemInt (hwnd, IDC_TEXT, iFreq, FALSE) ;
          return TRUE ;
         
    case WM_COMMAND:
          switch (LOWORD (wParam))
          {
          case IDC_ONOFF:
                    // If turning on waveform, hWaveOut is NULL
             
              if (hWaveOut == NULL)
              {
                        // Allocate memory for 2 headers and 2 buffers

                    pWaveHdr1 = malloc (sizeof (WAVEHDR)) ;
                    pWaveHdr2 = malloc (sizeof (WAVEHDR)) ;
                    pBuffer1  = malloc (OUT_BUFFER_SIZE) ;
                    pBuffer2  = malloc (OUT_BUFFER_SIZE) ;

                    if (!pWaveHdr1 || !pWaveHdr2 || !pBuffer1 || !pBuffer2)
                    {
                        if (!pWaveHdr1) free (pWaveHdr1) ;
                        if (!pWaveHdr2) free (pWaveHdr2) ;
                        if (!pBuffer1)  free (pBuffer1) ;
                        if (!pBuffer2)  free (pBuffer2) ;

                        MessageBeep (MB_ICONEXCLAMATION) ;
                        MessageBox (hwnd, TEXT ("Error allocating memory!"),
                                    szAppName, MB_ICONEXCLAMATION | MB_OK) ;
                        return TRUE ;
                    }

                        // Variable to indicate Off button pressed

                    bShutOff = FALSE ;
                       
                        // Open waveform audio for output
                       
                    waveformat.wFormatTag      = WAVE_FORMAT_PCM ;
                    waveformat.nChannels      = 1 ;
                    waveformat.nSamplesPerSec  = SAMPLE_RATE ;
                    waveformat.nAvgBytesPerSec = SAMPLE_RATE ;
                    waveformat.nBlockAlign    = 1 ;
                    waveformat.wBitsPerSample  = 8 ;
                    waveformat.cbSize          = 0 ;
                       
                    if (waveOutOpen (&hWaveOut, WAVE_MAPPER, &waveformat,
                                    (DWORD) hwnd, 0, CALLBACK_WINDOW)
                              != MMSYSERR_NOERROR)
                    {
                        free (pWaveHdr1) ;
                        free (pWaveHdr2) ;
                        free (pBuffer1) ;
                        free (pBuffer2) ;

                        hWaveOut = NULL ;
                        MessageBeep (MB_ICONEXCLAMATION) ;
                        MessageBox (hwnd,
                              TEXT ("Error opening waveform audio device!"),
                              szAppName, MB_ICONEXCLAMATION | MB_OK) ;
                        return TRUE ;
                    }

                        // Set up headers and prepare them

                    pWaveHdr1->lpData          = pBuffer1 ;
                    pWaveHdr1->dwBufferLength  = OUT_BUFFER_SIZE ;
                    pWaveHdr1->dwBytesRecorded = 0 ;
                    pWaveHdr1->dwUser          = 0 ;
                    pWaveHdr1->dwFlags        = 0 ;
                    pWaveHdr1->dwLoops        = 1 ;
                    pWaveHdr1->lpNext          = NULL ;
                    pWaveHdr1->reserved        = 0 ;
                   
                    waveOutPrepareHeader (hWaveOut, pWaveHdr1,
                                          sizeof (WAVEHDR)) ;

                    pWaveHdr2->lpData          = pBuffer2 ;
                    pWaveHdr2->dwBufferLength  = OUT_BUFFER_SIZE ;
                    pWaveHdr2->dwBytesRecorded = 0 ;
                    pWaveHdr2->dwUser          = 0 ;
                    pWaveHdr2->dwFlags        = 0 ;
                    pWaveHdr2->dwLoops        = 1 ;
                    pWaveHdr2->lpNext          = NULL ;
                    pWaveHdr2->reserved        = 0 ;
                   
                    waveOutPrepareHeader (hWaveOut, pWaveHdr2,
                                          sizeof (WAVEHDR)) ;
              }
                    // If turning off waveform, reset waveform audio
              else
              {
                    bShutOff = TRUE ;
                    waveOutReset (hWaveOut) ;
              }
              return TRUE ;
          }
          break ;

              // Message generated from waveOutOpen call
             
    case MM_WOM_OPEN:
          SetDlgItemText (hwnd, IDC_ONOFF, TEXT ("Turn Off")) ;

              // Send two buffers to waveform output device
                   
          FillBuffer (pBuffer1, iFreq) ;
          waveOutWrite (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
                   
          FillBuffer (pBuffer2, iFreq) ;
          waveOutWrite (hWaveOut, pWaveHdr2, sizeof (WAVEHDR)) ;
          return TRUE ;

              // Message generated when a buffer is finished
                   
    case MM_WOM_DONE:
          if (bShutOff)
          {
              waveOutClose (hWaveOut) ;
              return TRUE ;
          }

              // Fill and send out a new buffer

          FillBuffer (((PWAVEHDR) lParam)->lpData, iFreq) ;
          waveOutWrite (hWaveOut, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ;
          return TRUE ;
         
    case MM_WOM_CLOSE:
          waveOutUnprepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
          waveOutUnprepareHeader (hWaveOut, pWaveHdr2, sizeof (WAVEHDR)) ;

          free (pWaveHdr1) ;
          free (pWaveHdr2) ;
          free (pBuffer1) ;
          free (pBuffer2) ;

          hWaveOut = NULL ;
          SetDlgItemText (hwnd, IDC_ONOFF, TEXT ("Turn On")) ;
         
          if (bClosing)
              EndDialog (hwnd, 0) ;
         
          return TRUE ;
         
    case WM_SYSCOMMAND:
          switch (wParam)
          {
          case SC_CLOSE:
              if (hWaveOut != NULL)
              {
                    bShutOff = TRUE ;
                    bClosing = TRUE ;
                   
                    waveOutReset (hWaveOut) ;
              }
              else
                    EndDialog (hwnd, 0) ;
             
              return TRUE ;
          }
          break ;
    }
    return FALSE ;
}
Avatar billede kamikaze Nybegynder
19. april 2002 - 13:43 #2
(ovenstående kompilerer i et "Win32 Application" projekt under Visual C++)
Avatar billede kamikaze Nybegynder
19. april 2002 - 13:45 #3
Hov, du skal lige have en resource-fil med:

//resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by SineWave.rc
//
#define IDC_STATIC            -1
#define IDC_SCROLL                      1000
#define IDC_TEXT            1001
#define IDC_ONOFF                      1002

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        102
#define _APS_NEXT_COMMAND_VALUE        40001
#define _APS_NEXT_CONTROL_VALUE        1003
#define _APS_NEXT_SYMED_VALUE          101
#endif
#endif
Avatar billede kamikaze Nybegynder
19. april 2002 - 13:46 #4
Hvis du er interesseret kan du smide din email her, så sender jeg projektet til dig incl. alt.
Avatar billede Swift Praktikant
23. april 2002 - 08:49 #5
Jeg kan ikke lige få det til at virke - det ligner pointer-fejl...

Du må gerne sende det hele til:
swift@post7.te[REMOVE THIS]le.dk
Avatar billede kamikaze Nybegynder
23. april 2002 - 20:31 #6
(Hmmmm.... Hvorfor har du [REMOVE THIS] i din mailadr?) :-o
Avatar billede kamikaze Nybegynder
13. maj 2002 - 16:29 #7
Har du fundet ud af det????
Avatar billede Swift Praktikant
22. juni 2002 - 15:14 #8
Det virker nu!!
Takker for hjælpen!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester