DXライブラリ上でピストンノイズを鳴らす方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tarosa

DXライブラリ上でピストンノイズを鳴らす方法

#1

投稿記事 by tarosa » 15年前

みなさんこんにちは。
DXライブラリとhttp://hp.vector.co.jp/authors/VA022293/(BGM・効果音作成ソフト)について質問があります。
ピストンコラージュに付属のライブラリを使ってDXライブラリ上でピストンノイズ(効果音データ。拡張子はptnoise)を鳴らせてみようと下記のコードを書いたのですが、SoundHandleにエラー(-1)が返ってきてしまいます。
初歩的な質問で申し訳ございませんが、どこを直せばよいのかアドバイスをいただければ幸いです。
(なお、BGM(拡張子pttune)の方はピストンコラージュのライブラリに再生用の関数があるのでそれを使って再生できました)
・ソースコード本文
#include "DxLib.h"
#include "pxtone.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	int SoundHandle;
	PXTONENOISEBUFFER *p_noise;

	ChangeWindowMode(TRUE);
	if(DxLib_Init() == -1) return -1;

	pxtone_Ready(GetMainWindowHandle(), 2, 44100, 16, 0.1F, TRUE, NULL);
	p_noise = pxtone_Noise_Create("ameba.ptnoise", NULL, 1, 44100, 16);

	SoundHandle = LoadSoundMemByMemImage(p_noise->p_buf, p_noise->size);
	PlaySoundMem(SoundHandle, DX_PLAYTYPE_BACK);

	WaitKey();
	pxtone_Noise_Release(p_noise);
	pxtone_Release();
	DxLib_End();

	return 0;
}
・宣言部(ヘッダーから抜粋)
// pxtone を生成します。
BOOL DLLAPI pxtone_Ready(
	HWND hWnd,          // ウインドウハンドルを渡してください
	long channel_num,   // のチャンネル数を指定してください。( 1:モノラル / 2:ステレオ )
	long sps,           // 秒間サンプリングレートです。      ( 11025 / 22050 / 44100 )
	long bps,           // 1サンプルを表現するビット数です。( 8 / 16 )
	float buffer_sec,   // 曲を再生するのに使用するバッファサイズを秒で指定します。( 推奨 0.1 )
	BOOL bDirectSound,  // TRUE: DirectSound を使用します / FALSE: WAVEMAPPER を使用します。
	PXTONEPLAY_CALLBACK pProc // サンプリング毎に呼ばれる関数です。NULL でかまいません。
); // pxtone の準備

// ピストンノイズを生成します
typedef struct
{
	unsigned char* p_buf;
	int            size ;

}PXTONENOISEBUFFER;

void              DLLAPI  pxtone_Noise_Release( PXTONENOISEBUFFER* p_noise );
PXTONENOISEBUFFER DLLAPI *pxtone_Noise_Create(
	const char* name   ,     // リソース名      を設定。外部ファイルの場合はファイルパス。
	const char* type   ,     // リソースタイプ名を設定。外部ファイルの場合はNULL。
	long        channel_num, long sps, long bps );

Justy

Re:DXライブラリ上でピストンノイズを鳴らす方法

#2

投稿記事 by Justy » 15年前


>どこを直せばよいのかアドバイスをいただければ幸いです

 多分 pxtone_Noise_Create関数の戻り値である PXTONENOISEBUFFER内のデータは
生の波形データなのでしょう。

 なので、LoadSoundMemByMemImage関数に渡す前に WAVEファイルとしての
体裁を整えてあげれば(ファイルヘッダやチャンクを先頭に追加)再生できると
思います。

wav ファイルフォーマット
ttp://www.kk.iij4u.or.jp/~kondo/wave/

tarosa

Re:DXライブラリ上でピストンノイズを鳴らす方法

#3

投稿記事 by tarosa » 15年前

>  多分 pxtone_Noise_Create関数の戻り値である PXTONENOISEBUFFER内のデータは
> 生の波形データなのでしょう。

解説ページが消えてしまってもう見られないのですが、それによるとPCM WAVE形式にビルドしたバッファを返すと書かれていた記憶があります。
(とはいえ今は確認できないので勘違いかもしれません)

ヘッダやチャンクの追加方法は不勉強なためよくわからないのですが、試行錯誤してみるつもりです。
アドバイスどうもありがとうございました。

Justy

Re:DXライブラリ上でピストンノイズを鳴らす方法

#4

投稿記事 by Justy » 15年前

 ちょっと興味があったので、ライブラリをDLして、作ってみました。
 あんまりテストは足りてませんが、ひとまずこんな感じでやれば動くと思います。


[color=#d0d0ff" face="monospace]
#include "DxLib.h"
#include "pxtone.h"
#include <vector>
#include <cstring>

typedef std::vector<unsigned char> BufferType;

bool MakeWaveData_ByNoiseBuffer(BufferType &buffer,
const PXTONENOISEBUFFER *pNoise,
WORD channel, DWORD samplesPerSec, WORD bytePerSample)
{
if(!pNoise || !pNoise->p_buf || pNoise->size <= 0)
return false;

const size_t headerSize = 46;
size_t totalSize = headerSize + pNoise->size;

buffer.clear();
buffer.assign(totalSize, 0);

unsigned char *p = &buffer[0];
std::memcpy(p, "RIFF", sizeof(DWORD)); p += sizeof(DWORD);

*(DWORD*)p = totalSize - 8; p += sizeof(DWORD);
std::memcpy(p, "WAVE ", sizeof(DWORD)); p += sizeof(DWORD);

memcpy(p, "fmt ", sizeof(DWORD)); p += sizeof(DWORD);
*(DWORD*)p = sizeof(WAVEFORMATEX); p += sizeof(DWORD);

WAVEFORMATEX *pwf = (WAVEFORMATEX*)p;
pwf->wFormatTag = 1;
pwf->nChannels = channel;
pwf->nSamplesPerSec = samplesPerSec;
pwf->nAvgBytesPerSec = samplesPerSec * bytePerSample * channel;
pwf->nBlockAlign = bytePerSample * channel;
pwf->wBitsPerSample = bytePerSample * 8;
pwf->cbSize = 0;
p += sizeof(WAVEFORMATEX);

std::memcpy(p, "data ", sizeof(DWORD)); p += sizeof(DWORD);

*(DWORD*)p = pNoise->size; p += sizeof(DWORD);
std::memcpy(p, pNoise->p_buf, pNoise->size);

return true;
}

int LoadSoundMemByNoiseBuffer(const PXTONENOISEBUFFER *pNoise,
WORD channel, DWORD samplesPerSec, WORD bytePerSample)
{
BufferType buff;
if(MakeWaveData_ByNoiseBuffer(buff, pNoise, channel, samplesPerSec, bytePerSample))
{
int SoundHandle = LoadSoundMemByMemImage(
static_cast<void*>(&buff[0]), static_cast<int>(buff.size()));
return SoundHandle;
}
else
return -1;
}

int LoadSoundMemByPxtoneNoiseFile(const char *noiseFile,
WORD channel, DWORD samplesPerSec, WORD bytePerSample)
{
PXTONENOISEBUFFER * p_noise = pxtone_Noise_Create(noiseFile,
NULL, channel, samplesPerSec, bytePerSample * 8);
if(p_noise)
{
int handle = LoadSoundMemByNoiseBuffer(p_noise, channel, samplesPerSec, 2);
pxtone_Noise_Release(p_noise);
return handle;
}
else
return -1;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(TRUE);
if(DxLib_Init() == -1) return -1;

pxtone_Ready(GetMainWindowHandle(), 2, 44100, 16, 0.1F, TRUE, NULL);

int SoundHandle = LoadSoundMemByPxtoneNoiseFile("my_material/wood1.ptnoise", 1, 44100, 2);
if(SoundHandle != -1)
PlaySoundMem(SoundHandle, DX_PLAYTYPE_BACK);

WaitKey();

pxtone_Release();
DxLib_End();

return 0;
}
[/color]

tarosa

Re:DXライブラリ上でピストンノイズを鳴らす方法

#5

投稿記事 by tarosa » 15年前

ありがとうございます。こちらの方でも正常に動作することを確認できました。
こちらの勉強不足故にお手数をおかけして申し訳ありません。大いに参考にさせていただきます。

閉鎖

“C言語何でも質問掲示板” へ戻る