⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch2p1_tonegenerator.cpp

📁 游戏音频程序设计-Beginning.Game.Audio.Programming
💻 CPP
字号:
// Ch2p1_ToneGenerator.cpp : Defines the entry point for the console application.
//

#include <iostream>
#include <sstream>
#include <string>
#include <math.h>
#include <conio.h>

#include <dsound.h>
#include <dxerr8.h>
#include "dxutil.h"

using namespace std;
#define PI 3.14159

// tone frequencies: (C0 = lowest)

// C0      16.35      C#0/Db0 17.32      D0      18.35 
// D#0/Eb0 19.45      E0      20.60      F0      21.83 
// F#0/Gb0 23.12      G0      24.50      G#0/Ab0 25.96 
// A0      27.50      A#0/Bb0 29.14      B0      30.87 

// C1      32.70      C#1/Db1 34.65      D1      36.71 
// D#1/Eb1 38.89      E1      41.20      F1      43.65 
// F#1/Gb1 46.25      G1      49.00      G#1/Ab1 51.91 
// A1      55.00      A#1/Bb1 58.27      B1      61.74 

// C2      65.41      C#2/Db2 69.30      D2      73.42 
// D#2/Eb2 77.78      E2      82.41      F2      87.31 
// F#2/Gb2 92.50      G2      98.00      G#2/Ab2 103.83 
// A2      110.00     A#2/Bb2 116.54     B2      123.47 

// C3      130.81     C#3/Db3 138.59     D3      146.83  
// D#3/Eb3 155.56     E3      164.81     F3      174.61  
// F#3/Gb3 185.00     G3      196.00     G#3/Ab3 207.65 
// A3      220.00     A#3/Bb3 233.08     B3      246.94 

// C4      261.63     C#4/Db4 277.18     D4      293.66 
// D#4/Eb4 311.13     E4      329.63     F4      349.23  
// F#4/Gb4 369.99     G4      392.00     G#4/Ab4 415.30  
// A4      440.00     A#4/Bb4 466.16     B4      493.88  

// C5      523.25     C#5/Db5 554.37     D5      587.33  
// D#5/Eb5 622.25     E5      659.26     F5      698.46  
// F#5/Gb5 739.99     G5      783.99     G#5/Ab5 830.61  
// A5      880.00     A#5/Bb5 932.33     B5      987.77  

// C6      1046.50    C#6/Db6 1108.73    D6      1174.66  
// D#6/Eb6 1244.51    E6      1318.51    F6      1396.91  
// F#6/Gb6 1479.98    G6      1567.98    G#6/Ab6 1661.22  
// A6      1760.00    A#6/Bb6 1864.66    B6      1975.53  

// C7      2093.00    C#7/Db7 2217.46    D7      2349.32  
// D#7/Eb7 2489.02    E7      2637.02    F7      2793.83  
// F#7/Gb7 2959.96    G7      3135.96    G#7/Ab7 3322.44 
// A7      3520.00    A#7/Bb7 3729.31    B7      3951.07  

// C8      4186.01    C#8/Db8 4434.92    D8      4698.64  
// D#8/Eb8 4978.03

// global variables /////////////////////////////////////////////////////////

LPDIRECTSOUND8 g_pDS = NULL;

// code /////////////////////////////////////////////////////////////////////

HWND GetConsoleWindowHandle()
{
  char title[512];
  HWND hWnd;
 
  GetConsoleTitle(title, sizeof(title));
  hWnd = FindWindow(NULL, title);
  return(hWnd);
}

// InitAudio: initializes DirectX Audio
void InitAudio()
{
  HRESULT hr;
  stringstream err;

  // step 1: create primary DS interface
  if (FAILED(hr = DirectSoundCreate8(NULL, &g_pDS, NULL))) {
    err << "DirectSoundCreate8 failed: " << DXGetErrorString8(hr) << endl;
    throw(err.str());
  }

  // step 2: Set cooperative level                  
  if(FAILED(hr = g_pDS->SetCooperativeLevel(GetConsoleWindowHandle(), DSSCL_PRIORITY))) {
    err << "SetCooperativeLevel failed: " << DXGetErrorString8(hr) << endl;
    throw(err.str());
  }

  // step 3: Set primary buffer's format (stereo, 22050 Hz, 16 bits)
  {
    LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;

    // Get the primary buffer 
    DSBUFFERDESC dsbd;
    ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
    dsbd.dwSize        = sizeof(DSBUFFERDESC);
    dsbd.dwFlags       = DSBCAPS_PRIMARYBUFFER;
    dsbd.dwBufferBytes = 0;
    dsbd.lpwfxFormat   = NULL;
       
    // "create it" (or get it if it already exists, which it does)
    if( FAILED( hr = g_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) ) {
      err << "CreateSoundBuffer failed: " << DXGetErrorString8(hr) << endl;
      throw(err.str());
    }

    // set its format
    WAVEFORMATEX wfx;
    ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); 
    wfx.wFormatTag      = WAVE_FORMAT_PCM; 
    wfx.nChannels       = (WORD)2; 
    wfx.nSamplesPerSec  = 22050; // 22 Khz (CD quality is ~ 44 Khz, so this is "half-CD" quality)
    wfx.wBitsPerSample  = (WORD) 16; // 2 bytes per sample * 22050 samples/sec = 44100 bytes/sec)
    wfx.nBlockAlign     = (WORD) (wfx.wBitsPerSample / 8 * wfx.nChannels);
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

    if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) ) {
      err << "pSDBPrimary->SetFormat() failed: " << DXGetErrorString8(hr) << endl;
      throw(err.str());
    }

    // we're done with it, so release!
    SAFE_RELEASE( pDSBPrimary );
  } 
}

int CreateSecondaryBuffer(LPDIRECTSOUNDBUFFER *ppBuffer, int channels, 
                           int secs, int samplerate, int bitspersample, DWORD flags)
{
  HRESULT hr;
  stringstream err;
  
  DSBUFFERDESC dsbd;
  WAVEFORMATEX wfx;
  
  ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); 
  wfx.wFormatTag      = WAVE_FORMAT_PCM; 
  wfx.nChannels       = channels; 
  wfx.nSamplesPerSec  = samplerate; 
  wfx.wBitsPerSample  = bitspersample; 
  wfx.nBlockAlign     = (WORD) (wfx.wBitsPerSample / 8 * wfx.nChannels);
  wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

  ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
  dsbd.dwSize          = sizeof(DSBUFFERDESC);
  dsbd.dwFlags         = flags;
  dsbd.dwBufferBytes   = samplerate * bitspersample / 8 * channels * secs;
  dsbd.guid3DAlgorithm = GUID_NULL;
  dsbd.lpwfxFormat     = &wfx;

  if( FAILED( hr = g_pDS->CreateSoundBuffer( &dsbd, ppBuffer, NULL ) ) )
  {
      err << "CreateSecondaryBuffer: CreateSoundBuffer failed: " << DXGetErrorString8(hr) << endl;
      throw(err.str());;
  }
  return(dsbd.dwBufferBytes); // return size of buffer
}

void FillBuffer(LPDIRECTSOUNDBUFFER pBuffer, float frequency, int buffersize, int samplerate)
{
  HRESULT hr;
  stringstream err;
  unsigned char *pBufferBytes;
  DWORD lockedsize;

  // Lock the buffer down
  if(FAILED(hr = pBuffer->Lock(0, buffersize, (void **)(&pBufferBytes), 
           &lockedsize, NULL, NULL, 0L))) {
    err << "FillBuffer: Lock failed: " << DXGetErrorString8(hr) << endl;
    throw(err.str());;
  }

  for (DWORD q=0; q < lockedsize; q++) {
    /* What cycle are we in? */
    float pos = frequency/(float)samplerate*(float)q;
    /* Take fractional part of cycle and convert to degrees */
    float r = (pos - floor(pos)) * 2 * PI;
    float value = sin(r); // we now have a value somewhere between -1 and 1

    // change multiplier to change amplitude of wave aka volume
    pBufferBytes[q] = 127+(value * 127); 
  }

  // Unlock the buffer
  pBuffer->Unlock( pBufferBytes, lockedsize, NULL, 0 );
}

void PlayBuffer(LPDIRECTSOUNDBUFFER pBuffer)
{
  pBuffer->Play(0, 0, DSBPLAY_LOOPING);
}

void Exit(int errorcode)
{
  #ifdef _DEBUG
  cout << endl << endl << "(Program ended, press a key to exit.)";
  // so that the console window doesn't disappear before we have
  // a chance to look at it.
  getch(); 
#endif

  exit(errorcode);
} 

void main(int argc, char* argv[])
{
  LPDIRECTSOUNDBUFFER soundbuf;
  bool audioinited = false;

  try {

	  cout << "ToneGenerator" << endl << "=========================================" << endl;

    cout << "Initializing Audio..." << endl;
    // initialize DirectX Audio
    InitAudio();
    audioinited = true;

    // create secondary buffer
    cout << "Creating sound buffer..." << endl;
    int buffersize = CreateSecondaryBuffer(&soundbuf, 1, 1, 22010, 8, 0);

    // fill secondary buffer with tone data
    cout << "Filling sound buffer with data..." << endl;
    FillBuffer(soundbuf, 440.0, buffersize, 22010);  // 4th octave A note
    
    // tell user to turn down speakers
    cout << endl << endl << "*** TURN YOUR VOLUME DOWN ALL THE WAY! *** (then press a key)" << endl;
    getch();

    // play secondary buffer
    cout << "Playing buffer (slowly increase your volume, then hit a key to stop)..." << endl;
    PlayBuffer(soundbuf);
    getch();

    // stop secondary buffer
    soundbuf->Stop();

    // release secondary buffer
    cout << "Releasing sound buffer..." << endl;
    SAFE_RELEASE(soundbuf);

    // un-init DirectSound
    cout << "Un-Initializing Audio..." << endl;
    SAFE_RELEASE(g_pDS);

  }
  catch(string err) {
    cerr << err;
    Exit(-1);
  }

  Exit(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -