\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88/COgg.cpp on 'feature/Fixing_DirectSound_memoryleak' - RSS feed" href="/view?p=dtxmania/dtxmania.git;a=rss;f=DTXViewer%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/@FDK10%C3%A3%C2%83%C2%97%C3%A3%C2%83%C2%AD%C3%A3%C2%82%C2%B8%C3%A3%C2%82%C2%A7%C3%A3%C2%82%C2%AF%C3%A3%C2%83%C2%88/COgg.cpp;h=refs/heads/feature/Fixing_DirectSound_memoryleak" type="application/rss+xml" /> \83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88/COgg.cpp on 'feature/Fixing_DirectSound_memoryleak' - RSS feed (no merges)" href="/view?p=dtxmania/dtxmania.git;a=rss;f=DTXViewer%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/@FDK10%C3%A3%C2%83%C2%97%C3%A3%C2%83%C2%AD%C3%A3%C2%82%C2%B8%C3%A3%C2%82%C2%A7%C3%A3%C2%82%C2%AF%C3%A3%C2%83%C2%88/COgg.cpp;h=refs/heads/feature/Fixing_DirectSound_memoryleak;opt=--no-merges" type="application/rss+xml" /> \83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88/COgg.cpp on 'feature/Fixing_DirectSound_memoryleak' - Atom feed" href="/view?p=dtxmania/dtxmania.git;a=atom;f=DTXViewer%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/@FDK10%C3%A3%C2%83%C2%97%C3%A3%C2%83%C2%AD%C3%A3%C2%82%C2%B8%C3%A3%C2%82%C2%A7%C3%A3%C2%82%C2%AF%C3%A3%C2%83%C2%88/COgg.cpp;h=refs/heads/feature/Fixing_DirectSound_memoryleak" type="application/atom+xml" /> \83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88/COgg.cpp on 'feature/Fixing_DirectSound_memoryleak' - Atom feed (no merges)" href="/view?p=dtxmania/dtxmania.git;a=atom;f=DTXViewer%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/@FDK10%C3%A3%C2%83%C2%97%C3%A3%C2%83%C2%AD%C3%A3%C2%82%C2%B8%C3%A3%C2%82%C2%A7%C3%A3%C2%82%C2%AF%C3%A3%C2%83%C2%88/COgg.cpp;h=refs/heads/feature/Fixing_DirectSound_memoryleak;opt=--no-merges" type="application/atom+xml" />

OSDN Git Service

DirectSoundでClone()するとメモリリークする問題修正の途中版。WAVデータ実体への参照カウンタを実装済み。
[dtxmania/dtxmania.git] / DTXViewerプロジェクト / @FDK10ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88 / COgg.cpp
1 #include "stdafx.h"
2 #include "vorbis/vorbisfile.h"
3 #include "COgg.h"
4
5 namespace FDK {
6         namespace Sound {
7
8 static const WORD       s_bps = 2;      // byte / sample; \8cÅ\92è\92l
9
10 COgg::COgg()
11 {
12         this->bOpened           = false;
13
14         this->pOggData          = NULL;
15         this->dwTotalSize       = 0;
16         this->dwCurrentPos      = 0;
17
18         this->vi = NULL;
19 }
20
21
22 bool    COgg::Init( LPBYTE pOggRawData, DWORD dwOggRawDataSize )
23 {
24         if( ! pOggRawData )
25                 return false;   // \83f\81[\83^\83|\83C\83\93\83^\82ªNULL
26
27         if( this->bOpened )
28                 return false;   // \8aù\82É\83I\81[\83v\83\93\8dÏ\82Ý
29
30         this->pOggData          = pOggRawData;
31         this->dwTotalSize       = dwOggRawDataSize;
32         this->dwCurrentPos      = 0;
33
34         // ogg \82Ì\83\81\83\82\83\8a\83C\83\81\81[\83W\82©\82ç\82Ì\83R\81[\83\8b\83o\83b\83N\95t\82«\83I\81[\83v\83\93
35         static ov_callbacks s_callbackFunctions = {
36                 COgg::read,
37                 COgg::seek,
38                 COgg::close,
39                 COgg::tell
40         };
41
42         if( ov_open_callbacks( (void*)this, &this->vf, (char*)pOggRawData, (long)dwOggRawDataSize, s_callbackFunctions ) < 0 ) 
43         {
44                 //Debug::OutFN( FNAME, _T("ov_open() \82É\8e¸\94s\82µ\82Ü\82µ\82½\81B\n") );            \83w\83b\83_\83`\83F\83b\83N\82à\82©\82Ë\82Ä\82é\82Ì\82Å\83G\83\89\81[\83\81\83b\83Z\81[\83W\82Í\8fo\82³\82È\82¢\81B
45                 return false;
46         }
47
48         // ogg \82Ì\8fî\95ñ\8eæ\93¾
49         if( ( this->vi = ov_info( &this->vf, -1 ) ) == NULL )
50         {
51                 ov_clear( &this->vf );
52                 //Debug::OutFN( FNAME, _T("ov_info() \82É\8e¸\94s\82µ\82Ü\82µ\82½\81B\n") );            \83w\83b\83_\83`\83F\83b\83N\82à\82©\82Ë\82Ä\82é\82Ì\82Å\83G\83\89\81[\83\81\83b\83Z\81[\83W\82Í\8fo\82³\82È\82¢\81B
53                 return false;
54         }
55
56         this->bOpened = true;
57         this->bEOF = false;
58         return true;
59 }
60 size_t  COgg::GetDestSize()
61 {
62         if( ! this->bOpened )
63                 return 0;       // \83I\81[\83v\83\93\82³\82ê\82Ä\82È\82¢
64
65         _ASSERT( this->vi );
66
67         // \83f\83R\81[\83h\8cã\82Ì\83T\83C\83Y\82ð\8cv\8eZ
68         double dbDestSize = ceil( this->vi->channels * this->vi->rate * ov_time_total( &this->vf, -1) * s_bps );
69         if( dbDestSize < 0.0 )
70         {
71                 ov_clear( &this->vf );
72                 return 0;       // \8e¸\94s
73         }
74         return (size_t)dbDestSize;
75 }
76
77 bool    COgg::ConvertToWav( LPBYTE pDestBuf, size_t szDestBufSize )
78 {
79         if( ! pDestBuf || szDestBufSize <= 0 )
80                 return false;   // \83p\83\89\83\81\81[\83^\82ª\95s\90³
81
82         if( this->bEOF )
83                 return true;    // \82·\82Å\82É EOF \93\9e\92B\82¸\82Ý
84
85         // \83f\83R\81[\83h\81G
86         // \82P\89ñ\82Å\82·\82×\82Ä\82ª\83f\83R\81[\83h\82³\82ê\82é\82í\82¯\82Å\82Í\82È\82¢\82±\82Æ\82É\92\8d\88Ó\81B\81i\82P\89ñ\82É\82Â\82« 256\81`4096 bytes\82ç\82µ\82¢\81j
87         long lDecodedSize = 0;
88         int  nCurrent = 0;
89         while( szDestBufSize > (size_t)lDecodedSize )
90         {
91                 long ret = ov_read(
92                         &this->vf,                                                              // OggVobis_File
93                         (char*)(pDestBuf + lDecodedSize),               // \83o\83b\83t\83@\81G\8f\91\82«\8d\9e\82Þ\88Ê\92u
94                         (int)(szDestBufSize - lDecodedSize),    // \83o\83b\83t\83@\82Ì\83T\83C\83Y
95                         0,                                                                              // \83r\83b\83O\83G\83\93\83f\83B\83A\83\93\82È\82ç 1 \82É\82·\82é\81ix86 \82Í 0\81j
96                         s_bps,                                                                  // \8fo\97Í\83f\81[\83^\82Ì\97Ê\8eq\89»\83r\83b\83g\90\94\82ð\83o\83C\83g\92P\88Ê\82Å\8ew\92è\82·\82é\81B\97á\81F16bit\97Ê\8eq\89»\82Ì\8fê\8d\87\82Í2\81B
97                         1,                                                                              // \8fo\97Í\83f\81[\83^\82Ì\95\84\8d\86\8c`\8e®\81B0:\95\84\8d\86\82È\82µ\81A1:\95\84\8d\86\82 \82è\81BDirectSound \82Å\82Í\81A8bit\82È\82çunsigned, 16bit\82È\82çsigned \82Æ\82È\82é\81B
98                         &nCurrent );                                                    // \98_\97\9d\83r\83b\83g\83X\83g\83\8a\81[\83\80\82Ì\83|\83C\83\93\83^\81B
99
100                 if( ret < 0 )
101                         return false;   // ogg \82Ì\83f\83R\81[\83h\92\86\82É\83G\83\89\81[\82ª\94­\90
102                 else if( ret == 0 )
103                 {
104                         // eof \82É\93\9e\92B\82µ\82½\81¨\82Ü\82¾\8f\91\82«\8d\9e\82Ý\83o\83b\83t\83@\82ª\97]\82Á\82Ä\82¢\82ê\82Î\8fÁ\89¹\82ð\8f\91\82«\8d\9e\82Þ
105                         if( szDestBufSize > (size_t)lDecodedSize )
106                                 ZeroMemory( (void*)(pDestBuf + lDecodedSize), (int)(szDestBufSize - lDecodedSize) );
107                         this->bEOF = true;
108                         break;
109                 }
110
111                 lDecodedSize += ret;
112         }
113         return true;
114 }
115
116 bool    COgg::GetFormat( WAVEFORMATEX* pwfx )
117 {
118         if( ! pwfx )
119                 return false;   // \83p\83\89\83\81\81[\83^\82ª\95s\90³
120
121         if( ! this->bOpened )
122                 return false;   // ogg \82ª\83I\81[\83v\83\93\82³\82ê\82Ä\82È\82¢
123
124         ZeroMemory( pwfx, sizeof( WAVEFORMATEX ) );
125         pwfx->cbSize                            = 0;
126         pwfx->wFormatTag                        = WAVE_FORMAT_PCM;
127         pwfx->nChannels                         = this->vi->channels;
128         pwfx->nSamplesPerSec            = this->vi->rate;
129         pwfx->nAvgBytesPerSec           = this->vi->rate * this->vi->channels * s_bps;
130         pwfx->nBlockAlign                       = this->vi->channels * s_bps;
131         pwfx->wBitsPerSample            = s_bps * 8;
132         return true;
133 }
134
135 void    COgg::Term()
136 {
137         if( this->bOpened )
138         {
139                 ov_clear( &this->vf );
140                 this->bOpened = false;
141         }
142 }
143
144 void    COgg::RawSeek( long pos )
145 {
146         if( ! this->bOpened )
147                 return; // ogg \82ª\83I\81[\83v\83\93\82³\82ê\82Ä\82È\82¢
148
149         ov_raw_seek( &this->vf, pos );
150 }
151 void    COgg::PcmSeek( long pos )
152 {
153         if( ! this->bOpened )
154                 return; // ogg \82ª\83I\81[\83v\83\93\82³\82ê\82Ä\82È\82¢
155
156         ov_pcm_seek( &this->vf, pos );
157 }
158 size_t  COgg::read( void* ptr, size_t size, size_t nmemb, void* datasource )
159 {
160         if( ! datasource || ! ptr )
161                 return 0;       // EOF; \83p\83\89\83\81\81[\83^\82ª\95s\90³
162
163         COgg* pOgg = (COgg*)datasource;
164         _ASSERT( pOgg->pOggData );
165
166         if( pOgg->dwCurrentPos >= pOgg->dwTotalSize )
167                 return 0;       // EOF
168
169         size_t  readsize = size * nmemb;
170         if( pOgg->dwCurrentPos + readsize > pOgg->dwTotalSize )
171                 readsize = pOgg->dwTotalSize - pOgg->dwCurrentPos;
172
173         memcpy( ptr, pOgg->pOggData + pOgg->dwCurrentPos, readsize );
174         pOgg->dwCurrentPos += (DWORD) readsize;
175
176         return readsize;
177 }
178
179 int             COgg::seek( void* datasource, ogg_int64_t offset, int whence )
180 {
181         _ASSERT( datasource );
182         
183         COgg* pOgg = (COgg*)datasource;
184
185         switch( whence )
186         {
187         // a. \8dÅ\8f\89\82Ì\88Ê\92u\82©\82ç
188         case SEEK_SET:
189                 if( offset < 0 )
190                         pOgg->dwCurrentPos = 0;
191                 else
192                 {
193                         pOgg->dwCurrentPos = (DWORD) offset;
194                         if( pOgg->dwCurrentPos > pOgg->dwTotalSize )
195                                 pOgg->dwCurrentPos = pOgg->dwTotalSize;
196                 }
197                 break;
198
199         // b. \8dÅ\8cã\82Ì\88Ê\92u\82©\82ç
200         case SEEK_END:
201                 if( offset > 0 )
202                         pOgg->dwCurrentPos = pOgg->dwTotalSize;
203                 else if( -offset > pOgg->dwTotalSize )
204                         pOgg->dwCurrentPos = 0;
205                 else
206                         pOgg->dwCurrentPos = (DWORD)(pOgg->dwTotalSize + offset);
207                 break;
208
209         // c. \8c»\8dÝ\82Ì\88Ê\92u\82©\82ç
210         case SEEK_CUR:
211                 if( pOgg->dwCurrentPos + offset > pOgg->dwTotalSize )
212                         pOgg->dwCurrentPos = pOgg->dwTotalSize;
213                 else if( pOgg->dwCurrentPos < -offset )
214                         pOgg->dwCurrentPos = 0;
215                 else
216                         pOgg->dwCurrentPos = (DWORD)(pOgg->dwCurrentPos + offset);
217                 break;
218
219         default:
220                 return -1;      // \8e¸\94s
221         }
222
223         return 0;       // \90¬\8c÷
224 }
225
226 int             COgg::close( void* datasource )
227 {
228         _ASSERT( datasource );
229         COgg* pOgg = (COgg*)datasource;
230         
231         // \93Á\82É\89½\82à\82µ\82È\82¢
232         
233         return 0;
234 }
235
236 long    COgg::tell( void *datasource )
237 {
238         _ASSERT( datasource );
239         COgg* pOgg = (COgg*)datasource;
240
241         return pOgg->dwCurrentPos;
242 }
243
244         }//Sound
245 }//FDK