首页
社区
课程
招聘
谁对midiStream那几个api熟悉的?
发表于: 2006-6-3 21:43 6630

谁对midiStream那几个api熟悉的?

2006-6-3 21:43
6630
想在自己的小程序里加个midi背景音乐,以往是释放文件的方式来播放mid文件,感觉慢了点,这几天查msdn里发现有midiStream之类的api可以通过流方式不释放文件而直接播放midi音乐,自己试了几次返回的值和msdn上说的一样,但是不知道为什么没有声音:-(.
哪位有没有试过用这套api写过相关程序??

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 208
活跃值: (376)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
2
midiConnect                     将指定的MIDI输入设备连接到输出设备
midiDisconnect                  断开MIDI输入设备和输出设备的连接
midiInAddBuffer                 向指定的音乐仪器数字接口的输入设备增加
                               一个缓冲区

midiInClose                     关闭指定的音乐仪器数字接口的输入设备
midiInGetDveCaps                查询指定的音乐仪器数字接口的输入设备,
                               以确定其性能
midiInGetErrorText              检取有关音乐仪器数字接口的输入设备指定
                               错误的文本说明
midiInGetID                     获得一个音乐一起数字接口的输入设备的标
                               识符
midiInGetNumDevs                检取系统中音乐仪器数字接口的输入设备的
                               数量
midiInMessage                   向指定的音乐仪器数字接口的输入设备驱动
                               器发送一条消息
midiInOpen                      打开指定的音乐仪器数字接口的输入设备
midiInPrepareHeader             为音乐仪器数字接口的输入设备准备一个缓
                               冲区
midiInReset                     在给定的MIDI输入设备上输入,并将所有挂
                               起的输入缓冲区标记为已执行的
midiInStart                     启动在指定的音乐仪器数字接口的输入设备
                               上的输入
midiInStop                      停止在给定的音乐仪器数字接口的输入设备
                              上的输入
midiInUnprepareHeader          消除由midiInPrepareHeader函数完成的准备
midiOutCacheDrumPatches        请求内部的一个MIDI合成设备预装指定的基于
                              键的击打音色集
midiOutCachePatches            请求内部的音乐仪器数字接口的合成设备预装
                              指定的音色集
midiOutClose                   关闭指定的音乐仪器数字接口的输出设备
midiOutGetDevCaps              查询指定的音乐仪器数字接口的输出设备,以
                              确定其性能
midiOutGetErrorText            检取有关MIDI输出设备指定采取的文本说明
midiOutGetID                   检取指定的MIDI输出设备的标识符
midiOutGetNumDevs              检取系统中存在的MIDI输出设备的数量

midiOutGetVolume               返回一个MIDI输出设备的当前卷设置
midiOutLongMsg                 向指定的MIDI输出设备发送一条系统专用的
                              MIDI消息
midiOutMessage                 向一MIDI输出设备驱动器发送一条消息
midiOutOpen                    打开指定的MIDI输出设备进行回放
midiOutPrepareHeader           为MIDI输出设备准备一个缓冲区
midiOutReset                   为指定的MIDI输出设备关闭所有MIDI通道上的
                              所有标志
midiOutSetVolume               设置一个MIDI输出设备的卷
midiOutShortMsg                向指定的MIDI输出设备发送一条短MIDI消息
midiOutUnprepareHeader         清除由midiOutPrepareHeader函数完成的准备
midiStreamClose                关闭一个打开的MIDI流
midiStreamOpen                 为输出,打开一个MIDI流
midiStreamOut                  在MIDI输出设备上播放或排队一个MIDI数据流
midiStreamPause                暂停一个MIDI流的播放
midiStreamPosition             在一个MIDI流中检取当前位置
midiStreamProperty             设置或检取与MIDI输出设备相关MIDI数据流的
                              特性
midiStreamRestart              重新启动一个暂停的MIDI流
midiStreamStop                 关掉指定MIDI输出设备的所有MIDI通道

只有这些解释,但没具体用过!
2006-6-4 09:38
0
雪    币: 208
活跃值: (376)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
3
Re: Looking for Visual Basic Source Code
Posted by: moydog (IP Logged)
Date: April 19, 2006 10:45PM

Go here for the .frm

[www.blackbeltvb.com]

Option Explicit

' Midinote sample from BlackBeltVB.com
' [blackbeltvb.com]
'
' Written by Matt Hart
' Copyright 1999 by Matt Hart
'
' This software is FREEWARE. You may use it as you see fit for
' your own projects but you may not re-sell the original or the
' source code. Do not copy this sample to a collection, such as
' a CD-ROM archive. You may link directly to the original sample
' using "http://blackbeltvb.com/midinote.htm"
'
' No warranty express or implied, is given as to the use of this
' program. Use at your own risk.
'
' This one plays a few MIDI notes to the default MIDI
' device, showing you the basics of streaming MIDI output.
'
' It is a translation of a C program sent to me by
' Pier Calderan in the ' form of a question ...
' "How do I get this to work in VB?".

Private Type midiHdr
lpData As Long ' As String
dwBufferLength As Long
dwBytesRecorded As Long
dwUser As Long
dwFlags As Long
lpNext As Long
Reserved As Long
dwOffset As Long
dwReserved(0 To 3) As Long
End Type
Private Type MIDIPROPTIMEDIV
cbStruct As Long
dwTimeDiv As Long
End Type

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Declare Function midiOutPrepareHeader Lib "winmm.dll" (ByVal hMidiOut As Long, lpMidiOutHdr As Any, ByVal uSize As Long) As Long
Private Declare Function midiOutUnprepareHeader Lib "winmm.dll" (ByVal hMidiOut As Long, lpMidiOutHdr As Any, ByVal uSize As Long) As Long
Private Declare Function midiStreamClose Lib "winmm.dll" (ByVal hms As Long) As Long
Private Declare Function midiStreamOpen Lib "winmm.dll" (phms As Long, puDeviceID As Long, ByVal cMidi As Long, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal fdwOpen As Long) As Long
Private Declare Function midiStreamOut Lib "winmm.dll" (ByVal hms As Long, pmh As Any, ByVal cbmh As Long) As Long
Private Declare Function midiStreamProperty Lib "winmm.dll" (ByVal hms As Long, lppropdata As Any, ByVal dwProperty As Long) As Long
Private Declare Function midiStreamRestart Lib "winmm.dll" (ByVal hms As Long) As Long

Private Const GMEM_FIXED = &H0
Private Const GMEM_ZEROINIT = &H40
Private Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long

Private Const MIDIMAPPER = (-1)
Private Const MMSYSERR_NOERROR = 0
Private Const MIDIERR_BASE = 64
Private Const MIDIERR_STILLPLAYING = (MIDIERR_BASE + 1) ' still something playing
Private Const CALLBACK_NULL = &H0
Private Const MEVT_F_SHORT = &H0&
Private Const MIDIPROP_SET = &H80000000
Private Const MIDIPROP_TIMEDIV = &H1&

Private Sub Command1_Click()
Dim Phrase(0 To 18) As Long

Phrase(2) = &H7F3C90
Phrase(3) = 32
Phrase(5) = &H7F3E90
Phrase(8) = &H7F4090
Phrase(9) = 48
Phrase(11) = &H3C90
Phrase(12) = 48
Phrase(14) = &H3E90
Phrase(15) = 48
Phrase(17) = &H4090

Dim lSize As Long, uDevice As Long
lSize = (UBound(Phrase) - LBound(Phrase) + 1) * Len(Phrase(0))
uDevice = MIDIMAPPER

Dim Handle As Long, mHdr As midiHdr, hMem As Long, prop As MIDIPROPTIMEDIV

If midiStreamOpen(Handle, uDevice, 1, 0, 0, CALLBACK_NULL) = MMSYSERR_NOERROR Then
prop.cbStruct = Len(prop)
prop.dwTimeDiv = Val(Text1.Text)
midiStreamProperty Handle, prop, MIDIPROP_SET Or MIDIPROP_TIMEDIV

hMem = GlobalAlloc(GPTR, lSize)
CopyMemory ByVal hMem, Phrase(0), lSize

mHdr.lpData = hMem ' or VarPtr(Phrase(0)) without the global memory junk, but Phrase(0) might moved by VB unexpectedly
mHdr.dwBufferLength = lSize
mHdr.dwBytesRecorded = lSize - 4

If midiOutPrepareHeader(Handle, mHdr, Len(mHdr)) = MMSYSERR_NOERROR Then
midiStreamOut Handle, mHdr, Len(mHdr)
End If
midiStreamRestart Handle
Do While midiOutUnprepareHeader(Handle, mHdr, Len(mHdr)) = MIDIERR_STILLPLAYING: DoEvents: Loop
midiStreamClose Handle
GlobalFree hMem
End If
End Sub

Private Sub Form_Load()
Command1_Click
End Sub
2006-6-4 09:53
0
雪    币: 208
活跃值: (376)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
4
/*
    native_midi:  Hardware Midi support for the SDL_mixer library
    Copyright (C) 2000,2001  Florian 'Proff' Schulze

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Florian 'Proff' Schulze
    florian.proff.schulze@gmx.net

        $Id: native_midi_win32.c,v 1.3 2002/01/14 09:14:55 tksuoran Exp $
*/

/* everything below is currently one very big bad hack ;) Proff */

#define WIN32_LEAN_AND_MEAN
#include <stdlib.h>
#include <limits.h>
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <stdio.h>
#include "arch/win32/native_midi.h"

#define XCHG_SHORT(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
# define XCHG_LONG(x) ((((x)&0xFF)<<24) | \
                      (((x)&0xFF00)<<8) | \
                      (((x)&0xFF0000)>>8) | \
                      (((x)>>24)&0xFF))

#define LE_SHORT(x) x
#define LE_LONG(x) x
#define BE_SHORT(x) XCHG_SHORT(x)
#define BE_LONG(x) XCHG_LONG(x)

static UINT MidiDevice=MIDI_MAPPER;
static HMIDISTRM hMidiStream;
static NativeMidiSong *currentsong;

static int getvl(NativeMidiSong *song)
{
  int l=0;
  byte c;
  for (;;)
  {
    c=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
    song->CurrentPos++;
    l += (c & 0x7f);
    if (!(c & 0x80))
      return l;
    l<<=7;
  }
}

static void AddEvent(NativeMidiSong *song, DWORD at, DWORD type, byte event, byte a, byte b)
{
  MIDIEVENT *CurEvent;

  if ((song->BytesRecorded[song->CurrentTrack]+(int)sizeof(MIDIEVENT))>=song->BufferSize[song->CurrentTrack])
  {
    song->BufferSize[song->CurrentTrack]+=100*sizeof(MIDIEVENT);
    song->MidiEvents[song->CurrentTrack]=realloc(song->MidiEvents[song->CurrentTrack],song->BufferSize[song->CurrentTrack]);
  }
  CurEvent=(MIDIEVENT *)((byte *)song->MidiEvents[song->CurrentTrack]+song->BytesRecorded[song->CurrentTrack]);
  memset(CurEvent,0,sizeof(MIDIEVENT));
  CurEvent->dwDeltaTime=at;
  CurEvent->dwEvent=event+(a<<8)+(b<<16)+(type<<24);
  song->BytesRecorded[song->CurrentTrack]+=3*sizeof(DWORD);
}

static void MidiTracktoStream(NativeMidiSong *song)
{
  DWORD atime,len;
  byte event,type,a,b,c;
  byte laststatus,lastchan;

  song->CurrentPos=0;
  laststatus=0;
  lastchan=0;
  atime=0;
  for (;;)
  {
    if (song->CurrentPos>=song->mididata.track[song->CurrentTrack].len)
      return;
    atime+=getvl(song);
    event=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
    song->CurrentPos++;
    if(event==0xF0 || event == 0xF7) // SysEx event
    {
      len=getvl(song);
      song->CurrentPos+=len;
    }
    else if(event==0xFF) // Meta event
    {
      type=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
      song->CurrentPos++;
      len=getvl(song);
      switch(type)
        {
        case 0x2f:
          return;
        case 0x51: // Tempo
          a=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
          song->CurrentPos++;
          b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
          song->CurrentPos++;
          c=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
          song->CurrentPos++;
          AddEvent(song, atime, MEVT_TEMPO, c, b, a);
          break;
        default:
          song->CurrentPos+=len;
          break;
        }
    }
    else
    {
      a=event;
      if (a & 0x80) // status byte
      {
        lastchan=a & 0x0F;
        laststatus=(a>>4) & 0x07;
        a=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
        song->CurrentPos++;
        a &= 0x7F;
      }
      switch(laststatus)
      {
      case 0: // Note off
        b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
        song->CurrentPos++;
        b &= 0x7F;
        AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
        break;

      case 1: // Note on
        b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
        song->CurrentPos++;
        b &= 0x7F;
        AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
        break;

      case 2: // Key Pressure
        b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
        song->CurrentPos++;
        b &= 0x7F;
        AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
        break;

      case 3: // Control change
        b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
        song->CurrentPos++;
        b &= 0x7F;
        AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
        break;

      case 4: // Program change
        a &= 0x7f;
        AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, 0);
        break;

      case 5: // Channel pressure
        a &= 0x7f;
        AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, 0);
        break;

      case 6: // Pitch wheel
        b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
        song->CurrentPos++;
        b &= 0x7F;
        AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
        break;

      default:
        break;
      }
    }
  }
}

static int BlockOut(NativeMidiSong *song)
{
  MMRESULT err;
  int BlockSize;

  if ((song->MusicLoaded) && (song->NewEvents))
  {
    // proff 12/8/98: Added for savety
    midiOutUnprepareHeader((struct HMIDIOUT__ *)hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
    if (song->NewPos>=song->NewSize)
      return 0;
    BlockSize=(song->NewSize-song->NewPos);
    if (BlockSize<=0)
      return 0;
    if (BlockSize>36000)
      BlockSize=36000;
    song->MidiStreamHdr.lpData=(void *)((byte *)song->NewEvents+song->NewPos);
    song->NewPos+=BlockSize;
    song->MidiStreamHdr.dwBufferLength=BlockSize;
    song->MidiStreamHdr.dwBytesRecorded=BlockSize;
    song->MidiStreamHdr.dwFlags=0;
//    lprintf(LO_DEBUG,"Data: %p, Size: %i\n",MidiStreamHdr.lpData,BlockSize);
    err=midiOutPrepareHeader((struct HMIDIOUT__ *)hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
    if (err!=MMSYSERR_NOERROR)
      return 0;
    err=midiStreamOut(hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
      return 0;
  }
  return 1;
}

static void MIDItoStream(NativeMidiSong *song)
{
  int BufferPos[MIDI_TRACKS];
  MIDIEVENT *CurEvent;
  MIDIEVENT *NewEvent;
  int lTime;
  int Dummy;
  int Track;

  //if (!hMidiStream)
    //return;
  song->NewSize=0;
  for (song->CurrentTrack=0;song->CurrentTrack<MIDI_TRACKS;song->CurrentTrack++)
  {
    song->MidiEvents[song->CurrentTrack]=NULL;
    song->BytesRecorded[song->CurrentTrack]=0;
    song->BufferSize[song->CurrentTrack]=0;
    MidiTracktoStream(song);
    song->NewSize+=song->BytesRecorded[song->CurrentTrack];
    BufferPos[song->CurrentTrack]=0;
  }
  song->NewEvents=realloc(song->NewEvents,song->NewSize);
  if (song->NewEvents)
  {
    song->NewPos=0;
    while (1)
    {
      lTime=INT_MAX;
      Track=-1;
      for (song->CurrentTrack=MIDI_TRACKS-1;song->CurrentTrack>=0;song->CurrentTrack--)
      {
        if ((song->BytesRecorded[song->CurrentTrack]>0) && (BufferPos[song->CurrentTrack]<song->BytesRecorded[song->CurrentTrack]))
          CurEvent=(MIDIEVENT *)((byte *)song->MidiEvents[song->CurrentTrack]+BufferPos[song->CurrentTrack]);
        else
          continue;
        if ((int)CurEvent->dwDeltaTime<=lTime)
        {
          lTime=CurEvent->dwDeltaTime;
          Track=song->CurrentTrack;
        }
      }
      if (Track==-1)
        break;
      else
      {
        CurEvent=(MIDIEVENT *)((byte *)song->MidiEvents[Track]+BufferPos[Track]);
        BufferPos[Track]+=12;
        NewEvent=(MIDIEVENT *)((byte *)song->NewEvents+song->NewPos);
        memcpy(NewEvent,CurEvent,12);
        song->NewPos+=12;
      }
    }
    song->NewPos=0;
    lTime=0;
    while (song->NewPos<song->NewSize)
    {
      NewEvent=(MIDIEVENT *)((byte *)song->NewEvents+song->NewPos);
      Dummy=NewEvent->dwDeltaTime;
      NewEvent->dwDeltaTime-=lTime;
      lTime=Dummy;
      if ((song->NewPos+12)>=song->NewSize)
        NewEvent->dwEvent |= MEVT_F_CALLBACK;
      song->NewPos+=12;
    }
    song->NewPos=0;
    song->MusicLoaded=1;
    //BlockOut(song);
  }
  for (song->CurrentTrack=0;song->CurrentTrack<MIDI_TRACKS;song->CurrentTrack++)
  {
    if (song->MidiEvents[song->CurrentTrack])
      free(song->MidiEvents[song->CurrentTrack]);
  }
}

void CALLBACK MidiProc( HMIDIIN hMidi, UINT uMsg, DWORD dwInstance,
                        DWORD dwParam1, DWORD dwParam2 )
{
    switch( uMsg )
    {
    case MOM_DONE:
      if ((currentsong->MusicLoaded) && ((DWORD)dwParam1 == (DWORD)¤tsong->MidiStreamHdr))
        BlockOut(currentsong);
      break;
    case MOM_POSITIONCB:
      if ((currentsong->MusicLoaded) && ((DWORD)dwParam1 == (DWORD)¤tsong->MidiStreamHdr))
        currentsong->MusicPlaying=0;
      break;
    default:
      break;
    }
}

int native_midi_init()
{
  MMRESULT merr;
  HMIDISTRM MidiStream;

  merr=midiStreamOpen(&MidiStream,&MidiDevice,1,(DWORD)&MidiProc,0,CALLBACK_FUNCTION);
  if (merr!=MMSYSERR_NOERROR)
    MidiStream=0;
  midiStreamClose(MidiStream);
  if (!MidiStream)
    return 0;
  else
    return 1;
}

typedef struct
{
  char  ID[4];
  int   size;
  short format;
  short tracks;
  short deltatime;
} fmidihdr;

typedef struct
{
  char  ID[4];
  int   size;
} fmiditrack;

static void load_mididata(MIDI *mididata, FILE *fp)
{
  fmidihdr midihdr;
  fmiditrack trackhdr;
  int i;

  if (!mididata)
    return;
  if (!fp)
    return;
  fread(&midihdr,1,14,fp);
  mididata->divisions=BE_SHORT(midihdr.deltatime);
  for (i=0;i<BE_SHORT(midihdr.tracks);i++)
  {
    fread(&trackhdr,1,8,fp);
    mididata->track[i].len=BE_LONG(trackhdr.size);
    mididata->track[i].data=malloc(mididata->track[i].len);
    if (mididata->track[i].data)
      fread(mididata->track[i].data,1,mididata->track[i].len,fp);
  }
  mididata->loaded=1;
}

NativeMidiSong *native_midi_loadsong(char *midifile)
{
  FILE *fp;
  NativeMidiSong *newsong;

  newsong=malloc(sizeof(NativeMidiSong));
  if (!newsong)
    return NULL;
  memset(newsong,0,sizeof(NativeMidiSong));
  /* Open the file */
  fp = fopen(midifile, "rb");
  if ( fp != NULL )
  {
    newsong->mididata.loaded=0;
    load_mididata(&newsong->mididata, fp);
    if (!newsong->mididata.loaded)
    {
      free(newsong);
      fclose(fp);
      return NULL;
    }
    fclose(fp);
  }
  else
  {
    free(newsong);
    return NULL;
  }
  MIDItoStream(newsong);

  return newsong;
}

void native_midi_freesong(NativeMidiSong *song)
{
  if (hMidiStream)
  {
    midiStreamStop(hMidiStream);
    midiStreamClose(hMidiStream);
  }
  if (song)
  {
    if (song->NewEvents)
      free(song->NewEvents);
    free(song);
  }
}

void native_midi_start(NativeMidiSong *song)
{
  MMRESULT merr;
  MIDIPROPTIMEDIV mptd;

  native_midi_stop();
  if (!hMidiStream)
  {
    merr=midiStreamOpen(&hMidiStream,&MidiDevice,1,(DWORD)&MidiProc,0,CALLBACK_FUNCTION);
    if (merr!=MMSYSERR_NOERROR)
    {
      hMidiStream=0;
      return;
    }
    //midiStreamStop(hMidiStream);
//    MusicLoop=looping;
    currentsong=song;
    currentsong->NewPos=0;
    currentsong->MusicPlaying=1;
    mptd.cbStruct=sizeof(MIDIPROPTIMEDIV);
    mptd.dwTimeDiv=currentsong->mididata.divisions;
    merr=midiStreamProperty(hMidiStream,(LPBYTE)&mptd,MIDIPROP_SET | MIDIPROP_TIMEDIV);
    BlockOut(song);
    merr=midiStreamRestart(hMidiStream);
  }
}

void native_midi_stop()
{
  if (!hMidiStream)
    return;
  midiStreamStop(hMidiStream);
  midiStreamClose(hMidiStream);
  currentsong=NULL;
  hMidiStream = 0;
}

int native_midi_active()
{
  return currentsong->MusicPlaying;
}

void native_midi_setvolume(int volume)
{
}

char *native_midi_error()
{
  return "";
}
2006-6-4 09:58
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
5
这方面不熟悉,学习
2006-6-4 10:15
0
雪    币: 298
活跃值: (445)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
6
dwing发过用dx播放的代码。。。
用api感觉好麻烦,似乎是用MIDIEVENT来控制播放的,都不知道要和midi文件来如何转换,我对midi格式不熟悉,这里有个网站,看有没有用。。

typedef struct {
    DWORD dwDeltaTime;
    DWORD dwStreamID;
    DWORD dwEvent;
    DWORD dwParms[];
} MIDIEVENT;

http://www.borg.com/~jglatt/
2006-6-4 10:39
0
雪    币: 557
活跃值: (2303)
能力值: ( LV9,RANK:2130 )
在线值:
发帖
回帖
粉丝
7
Thx谢谢两位,写代码试试
2006-6-4 13:12
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
2006-6-4 15:51
0
游客
登录 | 注册 方可回帖
返回
//