midistrm.h
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:4k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. #pragma once
  2. // -----------------------------------------------------------------------------
  3. //
  4. //      THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  5. //      ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  6. //      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  7. //      PARTICULAR PURPOSE.
  8. //      Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.
  9. //
  10. // -----------------------------------------------------------------------------
  11. // Enable to turn on linear interpolation between samples in sine table
  12. // #instructions in inner loop: ~7 added
  13. #define MIDI_OPTIMIZE_LINEAR_INTERPOLATE 0
  14. #define NUMCHANNELS  (16)
  15. #define NUMENVELOPES (4)
  16. #define NUMNOTES     (32)
  17. // Special channel reserved for playing arbitrary tones
  18. #define FREQCHANNEL (NUMCHANNELS)
  19. class CMidiNote;
  20. class CMidiStream;
  21. typedef struct _ENVELOPE
  22. {
  23.     UINT32 Slope;
  24.     UINT32 Count;
  25. } ENVELOPE;
  26. class CMidiNote
  27. {
  28. public:
  29.     UINT32 NoteVal()      {return m_Note;}
  30.     UINT32 NoteChannel()  {return m_Channel;}
  31.     HRESULT NoteOn(CMidiStream *pMidiStream, UINT32 dwChannel, UINT32 dwNote, UINT32 dwVelocity);
  32.     HRESULT NoteOff(UINT32 dwVelocity);
  33.     PBYTE Render(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
  34.     PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
  35.     void GainChange();
  36.     void SetVelocity(UINT32 Velocity)
  37.     {
  38.         // Reset the bytes left value here. This ensures that if a note is going away we bring it back.
  39.         m_dwBytesLeft = (DWORD)-1;
  40.         m_Velocity = Velocity;
  41.         m_dwGain   = Velocity<<9;
  42.         GainChange();
  43.     }
  44.     LIST_ENTRY m_Link;
  45. private:
  46.     static const UINT32 PitchTable[12];                 // Pitch table
  47.     static const ENVELOPE EnvelopeTable[NUMENVELOPES];  // Envelope table
  48.     static const INT16 SineTable[0x101];                // Sine table
  49.     CMidiStream *m_pMidiStream;
  50.     UINT32 m_Note;
  51.     UINT32 m_Velocity;
  52.     UINT32 m_Channel;
  53.     UINT32 m_Index;          // Current index into wavetable
  54.     UINT32 m_IndexDelta;     // Amount to increment index on each sample
  55.     DWORD   m_dwGain;
  56.     DWORD   m_fxpGain;
  57.     DWORD   m_dwBytesLeft;
  58. };
  59. class CMidiStream : public StreamContext
  60. {
  61. public:
  62.     HRESULT Open(DeviceContext *pDeviceContext, LPWAVEOPENDESC lpWOD, DWORD dwFlags);
  63.     DWORD Close();
  64.     PBYTE Render(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
  65.     UINT32 DeltaTicksToByteCount(UINT32 DeltaTicks);
  66.     void NoteMoveToFreeList(CMidiNote *pCMidiNote)
  67.     {
  68.         PLIST_ENTRY pListEntry = &pCMidiNote->m_Link;
  69.         RemoveEntryList(pListEntry);
  70.         InsertTailList(&m_FreeList,pListEntry);
  71.     }
  72.     void NoteMoveToNoteList(CMidiNote *pCMidiNote)
  73.     {
  74.         PLIST_ENTRY pListEntry = &pCMidiNote->m_Link;
  75.         RemoveEntryList(pListEntry);
  76.         InsertTailList(&m_NoteList,pListEntry);
  77.     }
  78.     void NoteDone(CMidiNote *pCMidiNote)
  79.     {
  80.         NoteMoveToFreeList(pCMidiNote);
  81.         Release();
  82.     }
  83.     HRESULT NoteOn(UINT32 dwNote, UINT32 dwVelocity, UINT32 dwChannel);
  84.     HRESULT NoteOff(UINT32 dwNote, UINT32 dwVelocity, UINT32 dwChannel);
  85.     HRESULT AllNotesOff(UINT32 dwVelocity);
  86.     DWORD MidiMessage(UINT32 dwMsg);
  87.     HRESULT InternalMidiMessage(UINT32 dwData);
  88.     HRESULT MidiData(UINT32 dwData);
  89.     CMidiNote *FindNote(UINT32 dwNote, UINT32 dwChannel);
  90.     CMidiNote *AllocNote(UINT32 dwNote, UINT32 dwChannel);
  91.     UINT32 DeltaTicksToSamples(UINT32 DeltaTicks)
  92.     {
  93.         return (DeltaTicks * m_SamplesPerTick);
  94.     }
  95.     HRESULT UpdateTempo();
  96.     UINT32 ProcessMidiStream();
  97.     DWORD MapNoteGain(DWORD NoteGain);
  98.     void GainChange();
  99.     DWORD Reset();
  100. protected:
  101.     CMidiNote       m_MidiNote[NUMNOTES];
  102.     LIST_ENTRY      m_NoteList;
  103.     LIST_ENTRY      m_FreeList;
  104.     UINT32          m_ByteCount;
  105.     BYTE            m_RunningStatus;
  106.     UINT32          m_USecPerQuarterNote;     // Tempo, from midi stream
  107.     UINT32          m_TicksPerQuarterNote;    // PPQN, from midi header
  108.     UINT32          m_SamplesPerTick;         // Calculated as (SampleRate * Tempo)/(PPQN * 1000000)
  109.     UINT32          m_DeltaSampleCount;       // # of samples since last midi event (init to 0)
  110. };