作成者 |
メッセージ |
|
|
わざわざつくっていただいてすいません。
お手数お掛けしました。
ソースを(ざっと見て)比較してみたのですが
基本的には同じようです。
ほとんどがコピペのように一緒なのですが、
微妙に型が違っている部分が数箇所ありました。
そういえば作るときに勉強しながら大急ぎでつくったので
結構突貫工事だった気がします。
前回のミスといい、型が間違っていたようですね。(←もはや馬・・・)
それともう一点重要そうなのが、
いままでABのver3を使ったのですが、
konisiさんのソースをABver3で使うとエラーが沢山出ます。(これは当たり前として)
で、AB4用のものであると気づき実行してみると何の問題もなく出来ました。
連続演奏に対応するように書き換えたものも正常に動きました。
どうも旧バージョンに対する執着(?)が強かったのが原因のようです。
AB3でも型に気をつければ出来ると思ったのですが・・・。
ソースを手がかりに修正してみます。
わざわざありがとうございました。
わざわざつくっていただいてすいません。 お手数お掛けしました。 ソースを(ざっと見て)比較してみたのですが 基本的には同じようです。 ほとんどがコピペのように一緒なのですが、 微妙に型が違っている部分が数箇所ありました。 そういえば作るときに勉強しながら大急ぎでつくったので 結構突貫工事だった気がします。 前回のミスといい、型が間違っていたようですね。(←もはや馬・・・)
それともう一点重要そうなのが、 いままでABのver3を使ったのですが、 konisiさんのソースをABver3で使うとエラーが沢山出ます。(これは当たり前として) で、AB4用のものであると気づき実行してみると何の問題もなく出来ました。 連続演奏に対応するように書き換えたものも正常に動きました。 どうも旧バージョンに対する執着(?)が強かったのが原因のようです。 AB3でも型に気をつければ出来ると思ったのですが・・・。 ソースを手がかりに修正してみます。 わざわざありがとうございました。
|
|
|
投稿記事 |
Posted: 2008年8月10日(日) 13:22 |
|
|
|
|
|
試しに適当に作ってみたのですが、特にエラーは出ないようです。 [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: Type WAVEFORMATEX
wFormatTag As Word
nChannels As Word
nSamplesPerSec As DWord
nAvgBytesPerSec As DWord
nBlockAlign As Word
wBitsPerSample As Word
cbSize As Word
End Type
Type WAVEHDR
lpData As *Byte
dwBufferLength As DWord
dwBytesRecorded As DWord
dwUser As *DWord
dwFlags As DWord
dwLoops As DWord
lpNext As *WAVEHDR
reserved As *DWord
End Type
Const WHDR_DONE = 1
Const WHDR_PREPARED = 2
Const WHDR_BEGINLOOP = 4
Const WHDR_ENDLOOP = 8
Const WHDR_INQUEUE = 16
Const CALLBACK_FUNCTION = &H30000
Const CALLBACK_NULL = 0
Const CALLBACK_WINDOW = &H10000
Const WAVE_FORMAT_PCM=1
Const WAVE_MAPPER = -1
TypeDef MMRESULT = Long
TypeDef HWAVEOUT = HANDLE
TypeDef LPHWAVEOUT = *HWAVEOUT
TypeDef LPWAVEHDR = *WAVEHDR
TypeDef LPWAVEFORMATEX = *WAVEFORMATEX
Declare Function waveOutOpen Lib "winmm" (phwo As LPHWAVEOUT,uDeviceID As DWord,pwfx As LPWAVEFORMATEX,dwCallBack As VoidPtr,dwCallBackInstance As DWord,fdwOpen As DWord) As MMRESULT
Declare Function waveOutPrepareHeader Lib "winmm" (who As HWAVEOUT,pwh As LPWAVEHDR,cbwh As DWord) As MMRESULT
Declare Function waveOutWrite Lib "winmm" (hwo As HWAVEOUT,pwh As LPWAVEHDR,cbwh As DWord) As MMRESULT
Declare Function waveOutReset Lib "winmm" (hwo As HWAVEOUT) As MMRESULT
Declare Function waveOutUnprepareHeader Lib "winmm" (hwo As HWAVEOUT,pwh As LPWAVEHDR,cbwh As DWord) As MMRESULT
Declare Function waveOutClose Lib "winmm" (hwo As HWAVEOUT) As MMRESULT
'定義ここまで
#console
Const SRATE = 44100 '標本化周波数(1秒間のサンプル数)
Const MINUTES = 2 '秒数
Dim wfe As WAVEFORMATEX
wfe.wFormatTag=WAVE_FORMAT_PCM
wfe.nChannels=1'1=モノラル,2=ステレオ
wfe.wBitsPerSample=8'量子化ビット数 8ならデータは0...255 中心は128,16ならデータは-32768...32767中心は0
wfe.nBlockAlign=wfe.nChannels * wfe.wBitsPerSample/8
wfe.nSamplesPerSec=SRATE'標本化周波数
wfe.nAvgBytesPerSec=wfe.nSamplesPerSec * wfe.nBlockAlign
Dim hWaveOut As HWAVEOUT
waveOutOpen(VarPtr(hWaveOut),WAVE_MAPPER,VarPtr(wfe),0,0,CALLBACK_NULL)
Dim whdr As WAVEHDR,lpWave As *Byte
Dim len As Long,i As Long,elm As Long,k As Double
'波形の生成
elm=wfe.nSamplesPerSec*MINUTES
len=wfe.nAvgBytesPerSec*MINUTES
lpWave=calloc(elm*wfe.wBitsPerSample/8)
k=1/wfe.nAvgBytesPerSec*2*_System_PI
For i=0 To elm-1
lpWave=Sin(i*k*440)*64+128
Next
'再生
whdr.lpData=lpWave
whdr.dwBufferLength=len
whdr.dwFlags=WHDR_BEGINLOOP Or WHDR_ENDLOOP
whdr.dwLoops=1
waveOutPrepareHeader(hWaveOut,VarPtr(whdr),SizeOf(WAVEHDR))
waveOutWrite(hWaveOut,VarPtr(whdr),SizeOf(WAVEHDR))
'待機
Sleep(3000)
'再生終了
waveOutReset(hWaveOut)
waveOutUnprepareHeader(hWaveOut,VarPtr(whdr),SizeOf(WAVEHDR))
waveOutClose(hWaveOut)
free(lpWave)
ExitProcess(0)
試しに適当に作ってみたのですが、特にエラーは出ないようです。[hide][code]Type WAVEFORMATEX wFormatTag As Word nChannels As Word nSamplesPerSec As DWord nAvgBytesPerSec As DWord nBlockAlign As Word wBitsPerSample As Word cbSize As Word End Type
Type WAVEHDR lpData As *Byte dwBufferLength As DWord dwBytesRecorded As DWord dwUser As *DWord dwFlags As DWord dwLoops As DWord lpNext As *WAVEHDR reserved As *DWord End Type
Const WHDR_DONE = 1 Const WHDR_PREPARED = 2 Const WHDR_BEGINLOOP = 4 Const WHDR_ENDLOOP = 8 Const WHDR_INQUEUE = 16
Const CALLBACK_FUNCTION = &H30000 Const CALLBACK_NULL = 0 Const CALLBACK_WINDOW = &H10000
Const WAVE_FORMAT_PCM=1 Const WAVE_MAPPER = -1
TypeDef MMRESULT = Long TypeDef HWAVEOUT = HANDLE TypeDef LPHWAVEOUT = *HWAVEOUT TypeDef LPWAVEHDR = *WAVEHDR TypeDef LPWAVEFORMATEX = *WAVEFORMATEX
Declare Function waveOutOpen Lib "winmm" (phwo As LPHWAVEOUT,uDeviceID As DWord,pwfx As LPWAVEFORMATEX,dwCallBack As VoidPtr,dwCallBackInstance As DWord,fdwOpen As DWord) As MMRESULT Declare Function waveOutPrepareHeader Lib "winmm" (who As HWAVEOUT,pwh As LPWAVEHDR,cbwh As DWord) As MMRESULT Declare Function waveOutWrite Lib "winmm" (hwo As HWAVEOUT,pwh As LPWAVEHDR,cbwh As DWord) As MMRESULT Declare Function waveOutReset Lib "winmm" (hwo As HWAVEOUT) As MMRESULT Declare Function waveOutUnprepareHeader Lib "winmm" (hwo As HWAVEOUT,pwh As LPWAVEHDR,cbwh As DWord) As MMRESULT Declare Function waveOutClose Lib "winmm" (hwo As HWAVEOUT) As MMRESULT
'定義ここまで #console
Const SRATE = 44100 '標本化周波数(1秒間のサンプル数) Const MINUTES = 2 '秒数
Dim wfe As WAVEFORMATEX
wfe.wFormatTag=WAVE_FORMAT_PCM wfe.nChannels=1'1=モノラル,2=ステレオ wfe.wBitsPerSample=8'量子化ビット数 8ならデータは0...255 中心は128,16ならデータは-32768...32767中心は0 wfe.nBlockAlign=wfe.nChannels * wfe.wBitsPerSample/8 wfe.nSamplesPerSec=SRATE'標本化周波数 wfe.nAvgBytesPerSec=wfe.nSamplesPerSec * wfe.nBlockAlign
Dim hWaveOut As HWAVEOUT waveOutOpen(VarPtr(hWaveOut),WAVE_MAPPER,VarPtr(wfe),0,0,CALLBACK_NULL)
Dim whdr As WAVEHDR,lpWave As *Byte Dim len As Long,i As Long,elm As Long,k As Double '波形の生成 elm=wfe.nSamplesPerSec*MINUTES len=wfe.nAvgBytesPerSec*MINUTES lpWave=calloc(elm*wfe.wBitsPerSample/8) k=1/wfe.nAvgBytesPerSec*2*_System_PI For i=0 To elm-1 lpWave[i]=Sin(i*k*440)*64+128 Next
'再生 whdr.lpData=lpWave whdr.dwBufferLength=len whdr.dwFlags=WHDR_BEGINLOOP Or WHDR_ENDLOOP whdr.dwLoops=1 waveOutPrepareHeader(hWaveOut,VarPtr(whdr),SizeOf(WAVEHDR)) waveOutWrite(hWaveOut,VarPtr(whdr),SizeOf(WAVEHDR))
'待機 Sleep(3000)
'再生終了 waveOutReset(hWaveOut) waveOutUnprepareHeader(hWaveOut,VarPtr(whdr),SizeOf(WAVEHDR)) waveOutClose(hWaveOut) free(lpWave)
ExitProcess(0)[/code][/hide]
|
|
|
投稿記事 |
Posted: 2008年8月10日(日) 00:41 |
|
|
|
|
|
過去ログに似たようなものを発見したのですが
引用:
> ヒープ領域に対してメモリを確保(HeapAlloc,HeapReAlloc)した場合、
> 実は確保したメモリ以上にデータを扱う事ができます。
> これは確保されたヒープハンドルがハンドルに過ぎないためであり、
> たまたま未確保の領域を侵しても実害が無かっただけに過ぎません。
>
> しかし、幾ら実害が無くても確保したヒープ領域を開放(HeapFree)すると、
> 確保した領域外のデータまでクリアしてしまうみたいで
> 初めてエラーが発覚したりします。
>
> この辺はABというよりAPIの問題になってきますので、
> 一度MSDN等を参照されることをお勧めします。
>
> http://www.microsoft.com/japan/msdn/
とまけイヌさんが書いていました。(そういえばこの名を聞くのも久しぶりダ・・・)
takさんが言っていることと本質的には変わりないのですが、
なんか結構面倒そうになってきた。
過去ログに似たようなものを発見したのですが [quote] > ヒープ領域に対してメモリを確保(HeapAlloc,HeapReAlloc)した場合、 > 実は確保したメモリ以上にデータを扱う事ができます。 > これは確保されたヒープハンドルがハンドルに過ぎないためであり、 > たまたま未確保の領域を侵しても実害が無かっただけに過ぎません。 > > しかし、幾ら実害が無くても確保したヒープ領域を開放(HeapFree)すると、 > 確保した領域外のデータまでクリアしてしまうみたいで > 初めてエラーが発覚したりします。 > > この辺はABというよりAPIの問題になってきますので、 > 一度MSDN等を参照されることをお勧めします。 > > [url]http://www.microsoft.com/japan/msdn/[/url] [/quote] とまけイヌさんが書いていました。(そういえばこの名を聞くのも久しぶりダ・・・) takさんが言っていることと本質的には変わりないのですが、 なんか結構面倒そうになってきた。
|
|
|
投稿記事 |
Posted: 2008年8月09日(土) 23:47 |
|
|
|
|
|
書き忘れましたが、
SRATE-1(もしくは確保領域を増やす)をするとエラー頻度は確実に減ります。
しかし100%ではありません。
というかムリだったらもうこれでもいいかな、なんて思ってきました。
書き忘れましたが、 SRATE-1(もしくは確保領域を増やす)をするとエラー頻度は確実に減ります。 しかし100%ではありません。 というかムリだったらもうこれでもいいかな、なんて思ってきました。
|
|
|
投稿記事 |
Posted: 2008年8月09日(土) 23:19 |
|
|
|
|
|
ちょっとした改良なので即実行してみましたが
同様のエラーが出てしまいました。
似たような考えで確保する領域を増やす方法も考えたのですが
だめでした。
コード:
ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR))
pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ
For i=0 TO SRATE-1
pwh.lpData(i)=(i番目のデータ)←省略している
Next
pwh.dwBufferLength=SRATE
pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP
pwh.dwLoops=1
waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR))
waveOutWrite(hwo,pwh,sizeof(WAVEHDR))
それとやってて気づいたのですがwaveOutUnprepareHeaderのときにも
エラーが出るようです。こちらのエラーのほうが頻度が低いです。
コード:
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
Select Case dwMsg
case MM_WOM_DONE
waveOutUnprepareHeader(hWaveOut,pwh,sizeof(WAVEHDR)))←ここでもエラーが出る
HeapFree(GetProcessHeap(),0,pwh.lpData)←ここでエラーが出る
でそのときのエラーメッセージは
「スレッド(&HAC8)でアクセス違反がありました(EPI=&H76AF1F22)。」
というような感じになっています。
ちょっとした改良なので即実行してみましたが 同様のエラーが出てしまいました。 似たような考えで確保する領域を増やす方法も考えたのですが だめでした。 [code] ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR)) pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ For i=0 TO [b]SRATE-1[/b] pwh.lpData(i)=(i番目のデータ)←省略している Next pwh.dwBufferLength=SRATE pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP pwh.dwLoops=1 waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR)) waveOutWrite(hwo,pwh,sizeof(WAVEHDR)) [/code]
それとやってて気づいたのですがwaveOutUnprepareHeaderのときにも エラーが出るようです。こちらのエラーのほうが頻度が低いです。 [code] Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord ' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。 Select Case dwMsg case MM_WOM_DONE [b]waveOutUnprepareHeader(hWaveOut,pwh,sizeof(WAVEHDR)))←ここでもエラーが出る[/b] HeapFree(GetProcessHeap(),0,pwh.lpData)←ここでエラーが出る [/code] でそのときのエラーメッセージは 「スレッド(&HAC8)でアクセス違反がありました(EPI=&H76AF1F22)。」 というような感じになっています。
|
|
|
投稿記事 |
Posted: 2008年8月09日(土) 22:13 |
|
|
|
|
|
コード: For i=0 TO SRATE
pwh.lpData(i)=(i番目のデータ)←省略している
Next を コード: For i=0 TO SRATE-1
pwh.lpData(i)=(i番目のデータ)←省略している
Next にしてみたらどうなりますか?
[code]For i=0 TO SRATE pwh.lpData(i)=(i番目のデータ)←省略している Next [/code]を[code]For i=0 TO SRATE-1 pwh.lpData(i)=(i番目のデータ)←省略している Next [/code]にしてみたらどうなりますか?
|
|
|
投稿記事 |
Posted: 2008年8月09日(土) 14:15 |
|
|
|
|
|
返信ありがとうございます。
いろいろやっていたので返事が遅れてしまってすいません。
書き込み時に間違いがある、とのことでしたので、
書き込みの部分を調べてみました。
といっても書き込みを行う部分は前回投稿した部分のみなので
その辺で試したのですが、
コード:
ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR))
pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ
’ここをAとして
For i=0 TO SRATE
pwh.lpData(i)=(i番目のデータ)←省略している
Next
’ここをBとする。
pwh.dwBufferLength=SRATE
pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP
pwh.dwLoops=1
waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR))
waveOutWrite(hwo,pwh,sizeof(WAVEHDR))
上のコードでAの部分でメモリの解放を行ったところ問題はなく、
Bで解放したところ例のエラーが出ました。
つまり書き込みのこの部分に問題があったとわかりました。
コード:
For i=0 TO SRATE
pwh.lpData(i)=(i番目のデータ)←省略している
Next
そうなると怪しいのが省略してしまった部分なのですが、よく見ると
型を間違えてました(オイ)。ポインタと値がごっちゃになってましたので修復しました。
しかしどういうわけかこれでも改善がされません。
実際のところエラーが発生する回数は減ったのですが、
稀にエラーが出ています。
回数が少なくなったのは良いですがデバッグがしずらいです。
省略部分は音の合成の部分なのですがやはり省略した部分が
悪いのでしょうか?といってもソースを曝さなきゃわかりませんが
カオス過ぎて時間がかかりそうなのでとりあえず現状を報告しました。
返信ありがとうございます。 いろいろやっていたので返事が遅れてしまってすいません。 書き込み時に間違いがある、とのことでしたので、 書き込みの部分を調べてみました。 といっても書き込みを行う部分は前回投稿した部分のみなので その辺で試したのですが、 [code] ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR)) pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ ’ここをAとして For i=0 TO SRATE pwh.lpData(i)=(i番目のデータ)←省略している Next ’ここをBとする。 pwh.dwBufferLength=SRATE pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP pwh.dwLoops=1 waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR)) waveOutWrite(hwo,pwh,sizeof(WAVEHDR)) [/code] 上のコードでAの部分でメモリの解放を行ったところ問題はなく、 Bで解放したところ例のエラーが出ました。 つまり書き込みのこの部分に問題があったとわかりました。
[code] For i=0 TO SRATE pwh.lpData(i)=(i番目のデータ)←省略している Next [/code] そうなると怪しいのが省略してしまった部分なのですが、よく見ると 型を間違えてました(オイ)。ポインタと値がごっちゃになってましたので修復しました。 しかしどういうわけかこれでも改善がされません。 実際のところエラーが発生する回数は減ったのですが、 稀にエラーが出ています。 回数が少なくなったのは良いですがデバッグがしずらいです。 省略部分は音の合成の部分なのですがやはり省略した部分が 悪いのでしょうか?といってもソースを曝さなきゃわかりませんが カオス過ぎて時間がかかりそうなのでとりあえず現状を報告しました。
|
|
|
投稿記事 |
Posted: 2008年8月09日(土) 13:04 |
|
|
|
|
|
引用: HEAP[wavelast_debug.exe]: Heap block at 00191D30 modified at 0019C97C past requested size of ac44
スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。
HEAP[wavelast_debug.exe]: Invalid Address specified to RtlFreeHeap( 00140000, 00191D38 )
スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。
この警告メッセージは、HeapAlloc() で確保した領域の外にまで値を書き込んでしまったときのものです。
プログラムが debug 版なら、メモリ解放時に領域周辺が汚されていないかチェックして、もし汚れていたらこのような警告を吐いてブレークします。
この手のバグは見つけ出すのが難しいことも多いですが・・・
とりあえず、その領域に書き込むコードを重点的に調べてみてください。
たとえば、書き込む前にそのポインタが正しく領域内を指しているか逐一チェックするなど。
# そういえば Assert ってないんですかね。
[quote]HEAP[wavelast_debug.exe]: Heap block at 00191D30 modified at 0019C97C past requested size of ac44 スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。 HEAP[wavelast_debug.exe]: Invalid Address specified to RtlFreeHeap( 00140000, 00191D38 ) スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。[/quote] この警告メッセージは、HeapAlloc() で確保した領域の外にまで値を書き込んでしまったときのものです。 プログラムが debug 版なら、メモリ解放時に領域周辺が汚されていないかチェックして、もし汚れていたらこのような警告を吐いてブレークします。
この手のバグは見つけ出すのが難しいことも多いですが・・・ とりあえず、その領域に書き込むコードを重点的に調べてみてください。 たとえば、書き込む前にそのポインタが正しく領域内を指しているか逐一チェックするなど。
# そういえば Assert ってないんですかね。
|
|
|
投稿記事 |
Posted: 2008年8月07日(木) 21:50 |
|
|
|
|
|
waveoutをつかった音合成のプログラムを作っているのですが
debugするとメモリ解放時に
HEAP[wavelast_debug.exe]: Heap block at 00191D30 modified at 0019C97C past requested size of ac44
スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。
HEAP[wavelast_debug.exe]: Invalid Address specified to RtlFreeHeap( 00140000, 00191D38 )
スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。
というエラーが出ます。これってメモリのエラーですよね?
(経験上そう思う)
ところが実際にコンパイルしてみると 正常に動作します。
しかしエラーが出る以上はやはり問題があると思います。
メモリ上のエラーは致命的なので何とかしたいです。
実はメモリやwaveoutはあまり知らないので
勉強しながらやっている状態です。
ソースをさらしたいのですが超ロングぐだぐだクソースなため
見せるに忍びないので重要そうな部分をさらします。
メモリ確保から演奏開始まで
コード:
ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR))
pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ
For i=0 TO SRATE
pwh.lpData(i)=(i番目のデータ)←省略している
Next
pwh.dwBufferLength=SRATE
pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP
pwh.dwLoops=1
waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR))
waveOutWrite(hwo,pwh,sizeof(WAVEHDR))
で問題となる終了時はコールバックにて
コード: Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
Select Case dwMsg
case MM_WOM_DONE
waveOutUnprepareHeader(hWaveOut,pwh,sizeof(WAVEHDR))
HeapFree(GetProcessHeap(),0,pwh.lpData)←ここでエラーが出る
waveoutではwaveOutUnprepareHeaderとHeapFreeは
プログラム終了時だけではなく、演奏終了時にやらないと
メモリ使用量が上昇してしまうので抜け目なくやっているつもりです。
実際メモリ使用量も上がったり下がったりで困っています。
・・・どうでも良いですが実はVer2.0辺りからABをやっていて
掲示板にもちょくちょく顔を出していたのですが、いつの間にか行かなくなり
ABもVer3.0~4.0初期しか使用しておらず、最近来て見たら
Ver5.0とかの話になってて時代の流れを感じました。
waveoutをつかった音合成のプログラムを作っているのですが debugするとメモリ解放時に HEAP[wavelast_debug.exe]: Heap block at 00191D30 modified at 0019C97C past requested size of ac44 スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。 HEAP[wavelast_debug.exe]: Invalid Address specified to RtlFreeHeap( 00140000, 00191D38 ) スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。 というエラーが出ます。これってメモリのエラーですよね? (経験上そう思う)
ところが実際にコンパイルしてみると[b]正常に動作します。[/b] しかしエラーが出る以上はやはり問題があると思います。 メモリ上のエラーは致命的なので何とかしたいです。
実はメモリやwaveoutはあまり知らないので 勉強しながらやっている状態です。 ソースをさらしたいのですが超ロングぐだぐだクソースなため 見せるに忍びないので重要そうな部分をさらします。
メモリ確保から演奏開始まで [code] ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR)) pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ For i=0 TO SRATE pwh.lpData(i)=(i番目のデータ)←省略している Next pwh.dwBufferLength=SRATE pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP pwh.dwLoops=1 waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR)) waveOutWrite(hwo,pwh,sizeof(WAVEHDR))
[/code]
で問題となる終了時はコールバックにて
[code]Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord ' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。 Select Case dwMsg case MM_WOM_DONE waveOutUnprepareHeader(hWaveOut,pwh,sizeof(WAVEHDR)) HeapFree(GetProcessHeap(),0,pwh.lpData)←ここでエラーが出る [/code]
waveoutではwaveOutUnprepareHeaderとHeapFreeは プログラム終了時だけではなく、演奏終了時にやらないと メモリ使用量が上昇してしまうので抜け目なくやっているつもりです。 実際メモリ使用量も上がったり下がったりで困っています。
・・・どうでも良いですが実はVer2.0辺りからABをやっていて 掲示板にもちょくちょく顔を出していたのですが、いつの間にか行かなくなり ABもVer3.0~4.0初期しか使用しておらず、最近来て見たら Ver5.0とかの話になってて時代の流れを感じました。
|
|
|
投稿記事 |
Posted: 2008年8月07日(木) 17:06 |
|
|
|
|