System.Media.SoundPlayer
NET2.0ではSoundPlayerクラスが用意され、簡単にサウンドが使えるようになっています。試しにoggを演奏させるプログラムを書いてみました。
#include <windows.h> #include <Mmreg.h> #include <stdio.h> #include <math.h> #include <vorbis/codec.h> #include <vorbis/vorbisfile.h> #using <System.dll> using namespace System; using namespace System::IO; using namespace System::Media; #pragma pack (push, 1) typedef struct { short wFormatTag; unsigned short wChannels; unsigned long dwSamplesPerSec; unsigned long dwAvgBytesVerSec; unsigned short wBlockAlign; unsigned short wBitsPerSample; } FormatChunk; typedef struct { char cRIFF[4]; int iSizeRIFF; char cType[4]; char cFmt[4]; long chunkSize; FormatChunk chunk; char cData[4]; int iSizeData; } WAVEFILEHEADER; #pragma pack (pop) // ogg -> wave bool convert_to_wave (OggVorbis_File& vf, vorbis_info* vi, int word, array<unsigned char>^ bytes) { pin_ptr<unsigned char> p = &bytes [0]; char* output = reinterpret_cast<char*>(p); int cur; int nWrite = 0; int nRead = 0; while (true) { nWrite = ov_read (&vf, output + sizeof (WAVEFILEHEADER) + nRead, bytes->Length - nRead, 0, word, 1, &cur); if (nWrite == 0) break; else if (nWrite < 0) return false; else nRead += nWrite; } WAVEFILEHEADER wh; memcpy (wh.cRIFF, "RIFF", 4); wh.iSizeRIFF = sizeof (WAVEFILEHEADER) + nRead - 8; memcpy (wh.cType, "WAVE", 4); memcpy (wh.cFmt, "fmt ", 4); wh.chunkSize = sizeof (FormatChunk); wh.chunk.wFormatTag = WAVE_FORMAT_PCM; wh.chunk.wChannels = vi->channels; wh.chunk.dwSamplesPerSec = vi->rate; wh.chunk.dwAvgBytesVerSec= vi->rate * vi->channels * word; wh.chunk.wBlockAlign = vi->channels * word; wh.chunk.wBitsPerSample = word * 8; memcpy (wh.cData, "data", 4); wh.iSizeData = nRead; memcpy (output, &wh, sizeof (wh)); return true; } void main (int argc, char* argv[]) { if (argc < 1) { printf ("usage: playogg.exe file(.ogg)\n"); return; } FILE* fp; errno_t err; err = fopen_s (&fp, argv [1], "rb"); if (err != 0) { printf ("fopen_s failed.\n"); return; } OggVorbis_File vf; if (ov_open (fp, &vf, NULL, 0) < 0) { fclose (fp); fprintf (stderr, "ov_open failed.\n"); return; } vorbis_info* vi = ov_info (&vf, -1); if (vi == NULL) { ov_clear (&vf); fprintf (stderr, "ov_info failed.\n"); return; } int word = 2; double sec = ov_time_total (&vf, -1); printf ("%s - %02d:%02d\n", argv[1], (int)sec / 60, (int)sec % 60); int size = (LONG)ceil(vi->channels * vi->rate * sec * word); array<unsigned char>^ bytes = gcnew array<unsigned char>(size + sizeof (WAVEFILEHEADER)); bool ok = convert_to_wave (vf, vi, word, bytes); ov_clear (&vf); if (!ok) return; SoundPlayer^ player = gcnew SoundPlayer (gcnew MemoryStream (bytes)); player->PlayLooping (); // Hit any key Console::Read (); } /* playogg 02.ogg 02.ogg - 05:15 */
一度メモリに展開しているのが無駄なのでストリーミングにしようかと思いましたが時間切れ。(^^;