dxrubynd 1.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1516 @@
1
+ #define WINVER 0x0500 /* �o�[�W������` Windows2000�ȏ� */
2
+ #define DIRECTSOUND_VERSION 0x0900
3
+ #define _WIN32_WINNT WINVER
4
+
5
+ #include "ruby.h"
6
+ #ifndef RUBY_ST_H
7
+ #include "st.h"
8
+ #endif
9
+
10
+ #include <dmusici.h>
11
+
12
+ #define DXRUBY_EXTERN 1
13
+ #include "dxruby.h"
14
+ #include "sound.h"
15
+
16
+ #ifndef DS3DALG_DEFAULT
17
+ GUID DS3DALG_DEFAULT = {0};
18
+ #endif
19
+
20
+ #define WAVE_RECT 0
21
+ #define WAVE_SIN 1
22
+ #define WAVE_SAW 2
23
+ #define WAVE_TRI 3
24
+
25
+ static VALUE cSound; /* �T�E���h�N���X */
26
+ static VALUE cSoundEffect; /* �������ʉ��N���X */
27
+
28
+ static IDirectMusicPerformance8 *g_pDMPerformance = NULL; /* DirectMusicPerformance8�C���^�[�t�F�C�X */
29
+ static IDirectMusicLoader8 *g_pDMLoader = NULL; /* ���[�_�[ */
30
+ static LPDIRECTSOUND8 g_pDSound = NULL; /* DirectSound�C���^�[�t�F�C�X */
31
+ static int g_iRefDM = 0; /* DirectMusic�p�t�H�[�}���X�̎Q�ƃJ�E���g */
32
+ static int g_iRefDS = 0; /* DirectSound�̎Q�ƃJ�E���g */
33
+
34
+ /* Sound�I�u�W�F�N�g */
35
+ struct DXRubySound {
36
+ IDirectMusicAudioPath8 *pDMDefAudioPath; /* �f�t�H���g�I�[�f�B�I�p�X */
37
+ IDirectMusicSegment8 *pDMSegment; /* �Z�O�����g */
38
+ int start;
39
+ int loopstart;
40
+ int loopend;
41
+ int loopcount;
42
+ int midwavflag; /* mid��0�Awav��1 */
43
+ VALUE vbuffer;
44
+ };
45
+
46
+ /* SoundEffect�I�u�W�F�N�g */
47
+ struct DXRubySoundEffect {
48
+ LPDIRECTSOUNDBUFFER pDSBuffer; /* �o�b�t�@ */
49
+ };
50
+
51
+
52
+
53
+ /*********************************************************************
54
+ * Sound�N���X
55
+ *
56
+ * DirectMusic���g�p���ĉ���‚炷�B
57
+ * �Ƃ肠���������o�����Ɗ撣���Ă���B
58
+ *********************************************************************/
59
+
60
+ /*--------------------------------------------------------------------
61
+ �Q�Ƃ���Ȃ��Ȃ����Ƃ���GC����Ă΂��֐�
62
+ ---------------------------------------------------------------------*/
63
+ static void Sound_free( struct DXRubySound *sound )
64
+ {
65
+ HRESULT hr;
66
+
67
+ /* �T�E���h�I�u�W�F�N�g�̊J�� */
68
+ /* �o���h��� */
69
+ if ( sound->pDMSegment )
70
+ {
71
+ hr = sound->pDMSegment->lpVtbl->Unload( sound->pDMSegment, (IUnknown* )sound->pDMDefAudioPath );
72
+ if( FAILED( hr ) )
73
+ {
74
+ rb_raise( eDXRubyError, "Band release failed - Unload" );
75
+ }
76
+ /* �Z�O�����g���J�� */
77
+ RELEASE( sound->pDMSegment );
78
+ }
79
+
80
+ /* �f�t�H���g�I�[�f�B�I�p�X���J�� */
81
+ RELEASE( sound->pDMDefAudioPath );
82
+
83
+ g_iRefDM--;
84
+
85
+ if( g_iRefDM <= 0 )
86
+ {
87
+ /* ���t��~ */
88
+ if ( g_pDMPerformance )
89
+ {
90
+ hr = g_pDMPerformance->lpVtbl->Stop( g_pDMPerformance, NULL, NULL, 0, 0 );
91
+ if ( FAILED( hr ) )
92
+ {
93
+ rb_raise( eDXRubyError, "Stop performance failed - Stop" );
94
+ }
95
+ g_pDMPerformance->lpVtbl->CloseDown( g_pDMPerformance );
96
+ }
97
+ RELEASE(g_pDMPerformance);
98
+
99
+ /* ���[�_���J�� */
100
+ RELEASE(g_pDMLoader);
101
+ }
102
+ }
103
+
104
+ static void Sound_mark( struct DXRubySound *sound )
105
+ {
106
+ rb_gc_mark( sound->vbuffer );
107
+ }
108
+
109
+ static void Sound_release( struct DXRubySound *sound )
110
+ {
111
+ if ( sound->pDMSegment )
112
+ {
113
+ Sound_free( sound );
114
+ }
115
+ free( sound );
116
+ sound = NULL;
117
+
118
+ g_iRefAll--;
119
+ if( g_iRefAll == 0 )
120
+ {
121
+ CoUninitialize();
122
+ }
123
+ }
124
+
125
+ #ifdef DXRUBY_USE_TYPEDDATA
126
+ const rb_data_type_t Sound_data_type = {
127
+ "Sound",
128
+ {
129
+ Sound_mark,
130
+ Sound_release,
131
+ 0,
132
+ },
133
+ NULL, NULL
134
+ };
135
+ #endif
136
+
137
+ /*--------------------------------------------------------------------
138
+ Sound�N���X��dispose�B
139
+ ---------------------------------------------------------------------*/
140
+ static VALUE Sound_dispose( VALUE self )
141
+ {
142
+ struct DXRubySound *sound = DXRUBY_GET_STRUCT( Sound, self );
143
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
144
+ Sound_free( sound );
145
+ return self;
146
+ }
147
+
148
+ /*--------------------------------------------------------------------
149
+ Sound�N���X��disposed?�B
150
+ ---------------------------------------------------------------------*/
151
+ static VALUE Sound_check_disposed( VALUE self )
152
+ {
153
+ if( DXRUBY_GET_STRUCT( Sound, self )->pDMSegment == NULL )
154
+ {
155
+ return Qtrue;
156
+ }
157
+
158
+ return Qfalse;
159
+ }
160
+
161
+ /*--------------------------------------------------------------------
162
+ Sound�N���X��allocate�B���������m�ۂ���ׂ�initialize�O�ɌĂ΂��B
163
+ ---------------------------------------------------------------------*/
164
+ static VALUE Sound_allocate( VALUE klass )
165
+ {
166
+ VALUE obj;
167
+ struct DXRubySound *sound;
168
+
169
+ /* DXRubyImage�̃������擾��Image�I�u�W�F�N�g���� */
170
+ sound = malloc(sizeof(struct DXRubySound));
171
+ if( sound == NULL ) rb_raise( eDXRubyError, "Out of memory - Sound_allocate" );
172
+ #ifdef DXRUBY_USE_TYPEDDATA
173
+ obj = TypedData_Wrap_Struct( klass, &Sound_data_type, sound );
174
+ #else
175
+ obj = Data_Wrap_Struct(klass, 0, Sound_release, sound);
176
+ #endif
177
+ /* �Ƃ肠�����T�E���h�I�u�W�F�N�g��NULL�ɂ��Ă��� */
178
+ sound->pDMSegment = NULL;
179
+ sound->vbuffer = Qnil;
180
+
181
+ return obj;
182
+ }
183
+
184
+
185
+ /*--------------------------------------------------------------------
186
+ Sound�N���X��load_from_memory�B�t�@�C�������������烍�[�h����B
187
+ ---------------------------------------------------------------------*/
188
+ static VALUE Sound_load_from_memory( VALUE klass, VALUE vstr, VALUE vtype )
189
+ {
190
+ HRESULT hr;
191
+ WCHAR wstrFileName[MAX_PATH];
192
+ VALUE obj;
193
+ struct DXRubySound *sound;
194
+ CHAR strPath[MAX_PATH];
195
+ DWORD i;
196
+ WCHAR wstrSearchPath[MAX_PATH];
197
+ VALUE vsjisstr;
198
+
199
+ g_iRefAll++;
200
+
201
+ Check_Type( vstr, T_STRING );
202
+
203
+ if( g_iRefDM == 0 )
204
+ {
205
+ /* �p�t�H�[�}���X�̍쐬 */
206
+ hr = CoCreateInstance( &CLSID_DirectMusicPerformance, NULL,
207
+ CLSCTX_INPROC_SERVER, &IID_IDirectMusicPerformance8,
208
+ (void**)&g_pDMPerformance );
209
+ if( FAILED( hr ) )
210
+ {
211
+ rb_raise( eDXRubyError, "DirectMusic initialize error - CoCreateInstance" );
212
+ }
213
+
214
+ /* �p�t�H�[�}���X�̏����� */
215
+ hr = g_pDMPerformance->lpVtbl->InitAudio( g_pDMPerformance,
216
+ NULL, /* IDirectMusic�C���^�[�t�F�C�X�͕s�v */
217
+ NULL, /* IDirectSound�C���^�[�t�F�C�X�͕s�v */
218
+ g_hWnd, /* �E�B���h�E�̃n���h�� */
219
+ DMUS_APATH_SHARED_STEREOPLUSREVERB, /* �f�t�H���g�̃I�[�f�B�I�p�X�E�^�C�v */
220
+ 64, /* �p�t�H�[�}���X�E�`�����l���̐� */
221
+ DMUS_AUDIOF_ALL, /* �V���Z�T�C�U�̋@�\ */
222
+ NULL ); /* �I�[�f�B�I�E�p�����[�^�ɂ̓f�t�H���g���g�p */
223
+ if( FAILED( hr ) )
224
+ {
225
+ rb_raise( eDXRubyError, "DirectMusic initialize error - InitAudio" );
226
+ }
227
+
228
+ /* ���[�_�[�̍쐬 */
229
+ hr = CoCreateInstance( &CLSID_DirectMusicLoader, NULL,
230
+ CLSCTX_INPROC_SERVER, &IID_IDirectMusicLoader8,
231
+ (void**)&g_pDMLoader );
232
+ if( FAILED( hr ) )
233
+ {
234
+ rb_raise( eDXRubyError, "DirectMusic initialize error - CoCreateInstance" );
235
+ }
236
+
237
+ /* ���[�_�[�̏������i�����p�X���J�����g�E�f�B���N�g���ɐݒ�j */
238
+ i = GetCurrentDirectory( MAX_PATH, strPath );
239
+ if ( i == 0 || MAX_PATH < i )
240
+ {
241
+ rb_raise( eDXRubyError, "Get current directory failed - GetCurrentDirectory" );
242
+ }
243
+
244
+ /* �}���`�E�o�C�g������UNICODE�ɕϊ� */
245
+ MultiByteToWideChar( CP_ACP, 0, strPath, -1, wstrSearchPath, MAX_PATH );
246
+
247
+ /* ���[�_�[�Ɍ����p�X��ݒ� */
248
+ hr = g_pDMLoader->lpVtbl->SetSearchDirectory( g_pDMLoader, &GUID_DirectMusicAllTypes,
249
+ wstrSearchPath, FALSE );
250
+ if( FAILED( hr ) )
251
+ {
252
+ rb_raise( eDXRubyError, "Set directory failed - SetSearchDirectory" );
253
+ }
254
+ }
255
+ g_iRefDM++;
256
+
257
+ /* �T�E���h�I�u�W�F�N�g�擾 */
258
+ obj = Sound_allocate( klass );
259
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
260
+ if( sound->pDMSegment )
261
+ {
262
+ g_iRefDM++;
263
+ Sound_free( sound );
264
+ g_iRefDM--;
265
+ g_iRefAll--;
266
+ }
267
+
268
+ /* �I�[�f�B�I�E�p�X�쐬 */
269
+ hr = g_pDMPerformance->lpVtbl->CreateStandardAudioPath( g_pDMPerformance,
270
+ DMUS_APATH_DYNAMIC_STEREO, /* �p�X�̎�ށB */
271
+ 64, /* �p�t�H�[�}���X �`�����l���̐��B */
272
+ TRUE, /* �����ŃA�N�e�B�u�ɂȂ�B */
273
+ &sound->pDMDefAudioPath ); /* �I�[�f�B�I�p�X���󂯎��|�C���^�B */
274
+
275
+ if ( FAILED( hr ) )
276
+ {
277
+ rb_raise( eDXRubyError, "AudioPath set error - CreateStandardAudioPath" );
278
+ }
279
+
280
+ sound->vbuffer = vstr;
281
+
282
+ {
283
+ DMUS_OBJECTDESC desc;
284
+
285
+ ZeroMemory( &desc, sizeof(DMUS_OBJECTDESC) );
286
+ desc.dwSize = sizeof(DMUS_OBJECTDESC);
287
+ desc.dwValidData = DMUS_OBJ_MEMORY | DMUS_OBJ_CLASS;
288
+ desc.guidClass = CLSID_DirectMusicSegment;
289
+ desc.llMemLength = (LONGLONG)RSTRING_LEN(vstr); // �o�b�t�@�̃T�C�Y
290
+ desc.pbMemData = (LPBYTE)RSTRING_PTR(vstr); // �f�[�^�̓����Ă���o�b�t�@
291
+
292
+ hr = g_pDMLoader->lpVtbl->GetObject( g_pDMLoader, &desc, &IID_IDirectMusicSegment8, (void**)&sound->pDMSegment );
293
+ }
294
+
295
+ if( FAILED( hr ) )
296
+ {
297
+ sound->pDMSegment = NULL;
298
+ rb_raise( eDXRubyError, "Load error - LoadObjectFromFile" );
299
+ }
300
+
301
+ sound->start = 0;
302
+ sound->loopstart = 0;
303
+ sound->loopend = 0;
304
+
305
+ /* MIDI�̏ꍇ */
306
+ if( NUM2INT( vtype ) == 0 )
307
+ {
308
+ hr = sound->pDMSegment->lpVtbl->SetParam( sound->pDMSegment, &GUID_StandardMIDIFile,
309
+ 0xFFFFFFFF, 0, 0, NULL);
310
+ if( FAILED( hr ) )
311
+ {
312
+ rb_raise( eDXRubyError, "Load error - SetParam" );
313
+ }
314
+ sound->loopcount = DMUS_SEG_REPEAT_INFINITE;
315
+ sound->midwavflag = 0;
316
+ /* ���[�v�񐔐ݒ� */
317
+ hr = sound->pDMSegment->lpVtbl->SetRepeats( sound->pDMSegment, sound->loopcount );
318
+
319
+ if( FAILED( hr ) )
320
+ {
321
+ rb_raise( eDXRubyError, "Set loop count failed - SetRepeats" );
322
+ }
323
+ }
324
+ else
325
+ {
326
+ sound->loopcount = 1;
327
+ sound->midwavflag = 1;
328
+ }
329
+
330
+ /* �o���h�_�E�����[�h */
331
+ hr = sound->pDMSegment->lpVtbl->Download( sound->pDMSegment, (IUnknown* )sound->pDMDefAudioPath );
332
+
333
+ if( FAILED( hr ) )
334
+ {
335
+ rb_raise( eDXRubyError, "Band loading failed - Download" );
336
+ }
337
+
338
+
339
+ /* ���ʐݒ� */
340
+ hr = sound->pDMDefAudioPath->lpVtbl->SetVolume( sound->pDMDefAudioPath, 230 * 9600 / 255 - 9600 , 0 );
341
+
342
+ if( FAILED( hr ) )
343
+ {
344
+ rb_raise( eDXRubyError, "Set volume failed - SetVolume" );
345
+ }
346
+
347
+ return obj;
348
+ }
349
+
350
+
351
+ /*--------------------------------------------------------------------
352
+ Sound�N���X��initialize�B�t�@�C�������[�h����B
353
+ ---------------------------------------------------------------------*/
354
+ static VALUE Sound_initialize( VALUE obj, VALUE vfilename )
355
+ {
356
+ HRESULT hr;
357
+ WCHAR wstrFileName[MAX_PATH];
358
+ struct DXRubySound *sound;
359
+ CHAR strPath[MAX_PATH];
360
+ DWORD i;
361
+ WCHAR wstrSearchPath[MAX_PATH];
362
+ VALUE vsjisstr;
363
+
364
+ g_iRefAll++;
365
+
366
+ Check_Type(vfilename, T_STRING);
367
+
368
+ if( g_iRefDM == 0 )
369
+ {
370
+ /* �p�t�H�[�}���X�̍쐬 */
371
+ hr = CoCreateInstance( &CLSID_DirectMusicPerformance, NULL,
372
+ CLSCTX_INPROC_SERVER, &IID_IDirectMusicPerformance8,
373
+ (void**)&g_pDMPerformance );
374
+ if( FAILED( hr ) )
375
+ {
376
+ rb_raise( eDXRubyError, "DirectMusic initialize error - CoCreateInstance" );
377
+ }
378
+
379
+ /* �p�t�H�[�}���X�̏����� */
380
+ hr = g_pDMPerformance->lpVtbl->InitAudio( g_pDMPerformance,
381
+ NULL, /* IDirectMusic�C���^�[�t�F�C�X�͕s�v */
382
+ NULL, /* IDirectSound�C���^�[�t�F�C�X�͕s�v */
383
+ g_hWnd, /* �E�B���h�E�̃n���h�� */
384
+ DMUS_APATH_SHARED_STEREOPLUSREVERB, /* �f�t�H���g�̃I�[�f�B�I�p�X�E�^�C�v */
385
+ 64, /* �p�t�H�[�}���X�E�`�����l���̐� */
386
+ DMUS_AUDIOF_ALL, /* �V���Z�T�C�U�̋@�\ */
387
+ NULL ); /* �I�[�f�B�I�E�p�����[�^�ɂ̓f�t�H���g���g�p */
388
+ if( FAILED( hr ) )
389
+ {
390
+ rb_raise( eDXRubyError, "DirectMusic initialize error - InitAudio" );
391
+ }
392
+
393
+ /* ���[�_�[�̍쐬 */
394
+ hr = CoCreateInstance( &CLSID_DirectMusicLoader, NULL,
395
+ CLSCTX_INPROC_SERVER, &IID_IDirectMusicLoader8,
396
+ (void**)&g_pDMLoader );
397
+ if( FAILED( hr ) )
398
+ {
399
+ rb_raise( eDXRubyError, "DirectMusic initialize error - CoCreateInstance" );
400
+ }
401
+
402
+ /* ���[�_�[�̏������i�����p�X���J�����g�E�f�B���N�g���ɐݒ�j */
403
+ i = GetCurrentDirectory( MAX_PATH, strPath );
404
+ if ( i == 0 || MAX_PATH < i )
405
+ {
406
+ rb_raise( eDXRubyError, "Get current directory failed - GetCurrentDirectory" );
407
+ }
408
+
409
+ /* �}���`�E�o�C�g������UNICODE�ɕϊ� */
410
+ MultiByteToWideChar( CP_ACP, 0, strPath, -1, wstrSearchPath, MAX_PATH );
411
+
412
+ /* ���[�_�[�Ɍ����p�X��ݒ� */
413
+ hr = g_pDMLoader->lpVtbl->SetSearchDirectory( g_pDMLoader, &GUID_DirectMusicAllTypes,
414
+ wstrSearchPath, FALSE );
415
+ if( FAILED( hr ) )
416
+ {
417
+ rb_raise( eDXRubyError, "Set directory failed - SetSearchDirectory" );
418
+ }
419
+ }
420
+ g_iRefDM++;
421
+
422
+ /* �T�E���h�I�u�W�F�N�g�擾 */
423
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
424
+ if( sound->pDMSegment )
425
+ {
426
+ g_iRefDM++;
427
+ Sound_free( sound );
428
+ g_iRefDM--;
429
+ g_iRefAll--;
430
+ }
431
+
432
+ /* �I�[�f�B�I�E�p�X�쐬 */
433
+ hr = g_pDMPerformance->lpVtbl->CreateStandardAudioPath( g_pDMPerformance,
434
+ DMUS_APATH_DYNAMIC_STEREO, /* �p�X�̎�ށB */
435
+ 64, /* �p�t�H�[�}���X �`�����l���̐��B */
436
+ TRUE, /* �����ŃA�N�e�B�u�ɂȂ�B */
437
+ &sound->pDMDefAudioPath ); /* �I�[�f�B�I�p�X���󂯎��|�C���^�B */
438
+
439
+ if ( FAILED( hr ) )
440
+ {
441
+ rb_raise( eDXRubyError, "AudioPath set error - CreateStandardAudioPath" );
442
+ }
443
+
444
+ /* �t�@�C�����[�h */
445
+ if( rb_enc_get_index( vfilename ) != 0 )
446
+ {
447
+ vsjisstr = rb_str_export_to_enc( vfilename, g_enc_sys );
448
+ }
449
+ else
450
+ {
451
+ vsjisstr = vfilename;
452
+ }
453
+
454
+ MultiByteToWideChar( CP_ACP, 0, RSTRING_PTR( vsjisstr ), -1, wstrFileName, MAX_PATH );
455
+ hr = g_pDMLoader->lpVtbl->LoadObjectFromFile( g_pDMLoader, &CLSID_DirectMusicSegment,
456
+ &IID_IDirectMusicSegment8,
457
+ wstrFileName,
458
+ (LPVOID*)&sound->pDMSegment );
459
+ if( FAILED( hr ) )
460
+ {
461
+ sound->pDMSegment = NULL;
462
+ rb_raise( eDXRubyError, "Load error - LoadObjectFromFile" );
463
+ }
464
+
465
+ sound->start = 0;
466
+ sound->loopstart = 0;
467
+ sound->loopend = 0;
468
+
469
+ /* MIDI�̏ꍇ */
470
+ if( strstr( RSTRING_PTR( vsjisstr ), ".mid" ) != NULL )
471
+ {
472
+ hr = sound->pDMSegment->lpVtbl->SetParam( sound->pDMSegment, &GUID_StandardMIDIFile,
473
+ 0xFFFFFFFF, 0, 0, NULL);
474
+ if( FAILED( hr ) )
475
+ {
476
+ rb_raise( eDXRubyError, "Load error - SetParam" );
477
+ }
478
+ sound->loopcount = DMUS_SEG_REPEAT_INFINITE;
479
+ sound->midwavflag = 0;
480
+ /* ���[�v�񐔐ݒ� */
481
+ hr = sound->pDMSegment->lpVtbl->SetRepeats( sound->pDMSegment, sound->loopcount );
482
+
483
+ if( FAILED( hr ) )
484
+ {
485
+ rb_raise( eDXRubyError, "Set loop count failed - SetRepeats" );
486
+ }
487
+ }
488
+ else
489
+ {
490
+ sound->loopcount = 1;
491
+ sound->midwavflag = 1;
492
+ }
493
+
494
+ /* �o���h�_�E�����[�h */
495
+ hr = sound->pDMSegment->lpVtbl->Download( sound->pDMSegment, (IUnknown* )sound->pDMDefAudioPath );
496
+
497
+ if( FAILED( hr ) )
498
+ {
499
+ rb_raise( eDXRubyError, "Band loading failed - Download" );
500
+ }
501
+
502
+
503
+ /* ���ʐݒ� */
504
+ hr = sound->pDMDefAudioPath->lpVtbl->SetVolume( sound->pDMDefAudioPath, 230 * 9600 / 255 - 9600 , 0 );
505
+
506
+ if( FAILED( hr ) )
507
+ {
508
+ rb_raise( eDXRubyError, "Set volume failed - SetVolume" );
509
+ }
510
+
511
+ return obj;
512
+ }
513
+
514
+
515
+ /*--------------------------------------------------------------------
516
+ �J�n�ʒu��ݒ肷��
517
+ ---------------------------------------------------------------------*/
518
+ static VALUE Sound_setStart( VALUE obj, VALUE vstart )
519
+ {
520
+ HRESULT hr;
521
+ struct DXRubySound *sound;
522
+
523
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
524
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
525
+ sound->start = NUM2INT( vstart );
526
+
527
+ if( sound->midwavflag == 1 && sound->start > 0 ) /* wav�̏ꍇ */
528
+ {
529
+ hr = sound->pDMSegment->lpVtbl->SetLength( sound->pDMSegment, sound->start * DMUS_PPQ / 768 + 1 );
530
+ if( FAILED( hr ) )
531
+ {
532
+ rb_raise( eDXRubyError, "Set start point failed - SetLength" );
533
+ }
534
+ }
535
+
536
+ /* �Z�O�����g�Đ��X�^�[�g�ʒu�ݒ� */
537
+ hr = sound->pDMSegment->lpVtbl->SetStartPoint( sound->pDMSegment, sound->start * DMUS_PPQ / 768 );
538
+
539
+ if( FAILED( hr ) )
540
+ {
541
+ rb_raise( eDXRubyError, "Set start point failed - SetStartPoint" );
542
+ }
543
+
544
+ return obj;
545
+ }
546
+
547
+
548
+ /*--------------------------------------------------------------------
549
+ ���[�v�J�n�ʒu��ݒ肷��
550
+ ---------------------------------------------------------------------*/
551
+ static VALUE Sound_setLoopStart( VALUE obj, VALUE vloopstart )
552
+ {
553
+ HRESULT hr;
554
+ struct DXRubySound *sound;
555
+
556
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
557
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
558
+ sound->loopstart = NUM2INT( vloopstart );
559
+
560
+ if( sound->midwavflag == 1 )
561
+ {
562
+ rb_raise( eDXRubyError, "Can not be set to Wav data - Sound_loopStart=" );
563
+ }
564
+
565
+ if( sound->loopstart <= sound->loopend )
566
+ {
567
+ /* ���[�v�͈͐ݒ� */
568
+ hr = sound->pDMSegment->lpVtbl->SetLoopPoints( sound->pDMSegment, sound->loopstart * DMUS_PPQ / 768
569
+ , sound->loopend * DMUS_PPQ / 768 );
570
+ if( FAILED( hr ) )
571
+ {
572
+ rb_raise( eDXRubyError, "Set loop points failed - SetLoopPoints" );
573
+ }
574
+ }
575
+ else
576
+ {
577
+ /* ���[�v�͈͐ݒ� */
578
+ hr = sound->pDMSegment->lpVtbl->SetLoopPoints( sound->pDMSegment, 0, 0 );
579
+
580
+ if( FAILED( hr ) )
581
+ {
582
+ rb_raise( eDXRubyError, "Set loop points failed - SetLoopPoints" );
583
+ }
584
+ }
585
+
586
+ return obj;
587
+ }
588
+
589
+
590
+ /*--------------------------------------------------------------------
591
+ ���[�v�I���ʒu��ݒ肷��
592
+ ---------------------------------------------------------------------*/
593
+ static VALUE Sound_setLoopEnd( VALUE obj, VALUE vloopend )
594
+ {
595
+ HRESULT hr;
596
+ struct DXRubySound *sound;
597
+
598
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
599
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
600
+ sound->loopend = NUM2INT( vloopend );
601
+
602
+ if( sound->midwavflag == 1 )
603
+ {
604
+ rb_raise( eDXRubyError, "Can not be set to Wav data - Sound_loopEnd=" );
605
+ }
606
+
607
+ if( sound->loopstart <= sound->loopend )
608
+ {
609
+ /* ���[�v�͈͐ݒ� */
610
+ hr = sound->pDMSegment->lpVtbl->SetLoopPoints( sound->pDMSegment, sound->loopstart * DMUS_PPQ / 768
611
+ , sound->loopend * DMUS_PPQ / 768 );
612
+ if( FAILED( hr ) )
613
+ {
614
+ rb_raise( eDXRubyError, "Set loop points failed - SetLoopPoints" );
615
+ }
616
+ }
617
+ else
618
+ {
619
+ /* ���[�v�͈͐ݒ� */
620
+ hr = sound->pDMSegment->lpVtbl->SetLoopPoints( sound->pDMSegment, 0, 0 );
621
+
622
+ if( FAILED( hr ) )
623
+ {
624
+ rb_raise( eDXRubyError, "Set loop points failed - SetLoopPoints" );
625
+ }
626
+ }
627
+
628
+
629
+ return obj;
630
+ }
631
+
632
+
633
+ /*--------------------------------------------------------------------
634
+ ���[�v�񐔂�ݒ肷��
635
+ ---------------------------------------------------------------------*/
636
+ static VALUE Sound_setLoopCount( VALUE obj, VALUE vloopcount )
637
+ {
638
+ HRESULT hr;
639
+ struct DXRubySound *sound;
640
+
641
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
642
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
643
+ sound->loopcount = NUM2INT( vloopcount );
644
+
645
+ /* ���[�v�񐔐ݒ� */
646
+ hr = sound->pDMSegment->lpVtbl->SetRepeats( sound->pDMSegment, sound->loopcount );
647
+
648
+ if( FAILED( hr ) )
649
+ {
650
+ rb_raise( eDXRubyError, "Failed to set loop count - SetRepeats" );
651
+ }
652
+
653
+ return obj;
654
+ }
655
+
656
+
657
+ /*--------------------------------------------------------------------
658
+ ���ʂ�ݒ肷��
659
+ ---------------------------------------------------------------------*/
660
+ static VALUE Sound_setVolume( int argc, VALUE *argv, VALUE obj )
661
+ {
662
+ HRESULT hr;
663
+ struct DXRubySound *sound;
664
+ VALUE vvolume, vtime;
665
+ int volume, time;
666
+
667
+ rb_scan_args( argc, argv, "11", &vvolume, &vtime );
668
+
669
+ time = vtime == Qnil ? 0 : NUM2INT( vtime );
670
+ volume = NUM2INT( vvolume ) > 255 ? 255 : NUM2INT( vvolume );
671
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
672
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
673
+
674
+ /* ���ʐݒ� */
675
+ hr = sound->pDMDefAudioPath->lpVtbl->SetVolume( sound->pDMDefAudioPath, volume * 9600 / 255 - 9600, time );
676
+
677
+ if( FAILED( hr ) )
678
+ {
679
+ rb_raise( eDXRubyError, "Set volume error - SetVolume" );
680
+ }
681
+
682
+ return obj;
683
+ }
684
+
685
+
686
+ /*--------------------------------------------------------------------
687
+ �p�����擾����
688
+ ---------------------------------------------------------------------*/
689
+ static VALUE Sound_getPan( VALUE self )
690
+ {
691
+ HRESULT hr;
692
+ struct DXRubySound *sound;
693
+ IDirectSoundBuffer8* pDS3DBuffer;
694
+ long result;
695
+
696
+ sound = DXRUBY_GET_STRUCT( Sound, self );
697
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
698
+
699
+ hr = sound->pDMDefAudioPath->lpVtbl->GetObjectInPath( sound->pDMDefAudioPath, DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, &GUID_NULL, 0, &IID_IDirectSoundBuffer8, (LPVOID*) &pDS3DBuffer);
700
+
701
+ if( FAILED( hr ) )
702
+ {
703
+ rb_raise( eDXRubyError, "internal error - GetPan" );
704
+ }
705
+
706
+ /* �p���擾 */
707
+ hr = pDS3DBuffer->lpVtbl->GetPan( pDS3DBuffer, &result );
708
+
709
+ if( FAILED( hr ) )
710
+ {
711
+ rb_raise( eDXRubyError, "pan get error - GetPan" );
712
+ }
713
+
714
+ RELEASE( pDS3DBuffer );
715
+
716
+ return INT2NUM( result );
717
+ }
718
+
719
+
720
+ /*--------------------------------------------------------------------
721
+ �p����ݒ肷��
722
+ ---------------------------------------------------------------------*/
723
+ static VALUE Sound_setPan( VALUE self, VALUE vpan )
724
+ {
725
+ HRESULT hr;
726
+ struct DXRubySound *sound;
727
+ IDirectSoundBuffer8* pDS3DBuffer;
728
+
729
+ sound = DXRUBY_GET_STRUCT( Sound, self );
730
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
731
+
732
+ hr = sound->pDMDefAudioPath->lpVtbl->GetObjectInPath( sound->pDMDefAudioPath, DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, &GUID_NULL, 0, &IID_IDirectSoundBuffer8, (LPVOID*) &pDS3DBuffer);
733
+
734
+ if( FAILED( hr ) )
735
+ {
736
+ rb_raise( eDXRubyError, "internal error - SetPan" );
737
+ }
738
+
739
+ /* �p���ݒ� */
740
+ hr = pDS3DBuffer->lpVtbl->SetPan( pDS3DBuffer, NUM2INT( vpan ) );
741
+
742
+ if( FAILED( hr ) )
743
+ {
744
+ rb_raise( eDXRubyError, "pan setting error - SetPan" );
745
+ }
746
+
747
+ RELEASE( pDS3DBuffer );
748
+
749
+ return self;
750
+ }
751
+
752
+
753
+ /*--------------------------------------------------------------------
754
+ ���g�����擾����
755
+ ---------------------------------------------------------------------*/
756
+ static VALUE Sound_getFrequency( VALUE self )
757
+ {
758
+ HRESULT hr;
759
+ struct DXRubySound *sound;
760
+ IDirectSoundBuffer8* pDS3DBuffer;
761
+ DWORD result;
762
+
763
+ sound = DXRUBY_GET_STRUCT( Sound, self );
764
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
765
+
766
+ hr = sound->pDMDefAudioPath->lpVtbl->GetObjectInPath( sound->pDMDefAudioPath, DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, &GUID_NULL, 0, &IID_IDirectSoundBuffer8, (LPVOID*) &pDS3DBuffer);
767
+
768
+ if( FAILED( hr ) )
769
+ {
770
+ rb_raise( eDXRubyError, "internal error - GetPan" );
771
+ }
772
+
773
+ /* ���g���擾 */
774
+ hr = pDS3DBuffer->lpVtbl->GetFrequency( pDS3DBuffer, &result );
775
+
776
+ if( FAILED( hr ) )
777
+ {
778
+ rb_raise( eDXRubyError, "frequency get error - getFrequency" );
779
+ }
780
+
781
+ RELEASE( pDS3DBuffer );
782
+
783
+ return UINT2NUM( result );
784
+ }
785
+
786
+
787
+ /*--------------------------------------------------------------------
788
+ ���g����ݒ肷��
789
+ ---------------------------------------------------------------------*/
790
+ static VALUE Sound_setFrequency( VALUE self, VALUE vfrequency )
791
+ {
792
+ HRESULT hr;
793
+ struct DXRubySound *sound;
794
+ IDirectSoundBuffer8* pDS3DBuffer;
795
+
796
+ sound = DXRUBY_GET_STRUCT( Sound, self );
797
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
798
+
799
+ hr = sound->pDMDefAudioPath->lpVtbl->GetObjectInPath( sound->pDMDefAudioPath, DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, &GUID_NULL, 0, &IID_IDirectSoundBuffer8, (LPVOID*) &pDS3DBuffer);
800
+
801
+ if( FAILED( hr ) )
802
+ {
803
+ rb_raise( eDXRubyError, "internal error - SetPan" );
804
+ }
805
+
806
+ /* ���g���ݒ� */
807
+ hr = pDS3DBuffer->lpVtbl->SetFrequency( pDS3DBuffer, NUM2UINT( vfrequency ) );
808
+
809
+ if( FAILED( hr ) )
810
+ {
811
+ rb_raise( eDXRubyError, "frequency setting error - setFrequency" );
812
+ }
813
+
814
+ RELEASE( pDS3DBuffer );
815
+
816
+ return self;
817
+ }
818
+
819
+
820
+ /*--------------------------------------------------------------------
821
+ ����‚炷
822
+ ---------------------------------------------------------------------*/
823
+ static VALUE Sound_play( VALUE obj )
824
+ {
825
+ HRESULT hr;
826
+ struct DXRubySound *sound;
827
+
828
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
829
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
830
+
831
+ /* �� */
832
+ if( sound->midwavflag == 0 )
833
+ {
834
+ hr = g_pDMPerformance->lpVtbl->PlaySegmentEx( g_pDMPerformance, (IUnknown* )sound->pDMSegment, NULL, NULL,
835
+ DMUS_SEGF_CONTROL, 0, NULL, NULL, (IUnknown* )sound->pDMDefAudioPath );
836
+ }
837
+ else
838
+ {
839
+ hr = g_pDMPerformance->lpVtbl->PlaySegmentEx( g_pDMPerformance, (IUnknown* )sound->pDMSegment, NULL, NULL,
840
+ DMUS_SEGF_SECONDARY, 0, NULL, NULL, (IUnknown* )sound->pDMDefAudioPath );
841
+ }
842
+ if( FAILED( hr ) )
843
+ {
844
+ rb_raise( eDXRubyError, "Sound play failed - PlaySegmentEx" );
845
+ }
846
+
847
+ return obj;
848
+ }
849
+
850
+
851
+ /*--------------------------------------------------------------------
852
+ �����~�߂�
853
+ ---------------------------------------------------------------------*/
854
+ static VALUE Sound_stop( VALUE obj )
855
+ {
856
+ HRESULT hr;
857
+ struct DXRubySound *sound;
858
+
859
+ sound = DXRUBY_GET_STRUCT( Sound, obj );
860
+ DXRUBY_CHECK_DISPOSE( sound, pDMSegment );
861
+
862
+ /* �� */
863
+ hr = g_pDMPerformance->lpVtbl->StopEx( g_pDMPerformance, (IUnknown* )sound->pDMSegment, 0, 0 );
864
+
865
+ if( FAILED( hr ) )
866
+ {
867
+ rb_raise( eDXRubyError, "Sound stop failed - StopEx" );
868
+ }
869
+
870
+ return obj;
871
+
872
+ }
873
+
874
+
875
+ /*********************************************************************
876
+ * SoundEffect�N���X
877
+ *
878
+ * DirectSound���g�p���ĉ���‚炷�B
879
+ * �Ƃ肠���������o�����Ɗ撣���Ă���B
880
+ *********************************************************************/
881
+
882
+ /*--------------------------------------------------------------------
883
+ �Q�Ƃ���Ȃ��Ȃ����Ƃ���GC����Ă΂��֐�
884
+ ---------------------------------------------------------------------*/
885
+ static void SoundEffect_free( struct DXRubySoundEffect *soundeffect )
886
+ {
887
+ /* �T�E���h�o�b�t�@���J�� */
888
+ RELEASE( soundeffect->pDSBuffer );
889
+
890
+ g_iRefDS--;
891
+
892
+ if( g_iRefDS == 0 )
893
+ {
894
+ RELEASE( g_pDSound );
895
+ }
896
+
897
+ }
898
+
899
+ static void SoundEffect_release( struct DXRubySoundEffect *soundeffect )
900
+ {
901
+ if( soundeffect->pDSBuffer )
902
+ {
903
+ SoundEffect_free( soundeffect );
904
+ }
905
+ free( soundeffect );
906
+ soundeffect = NULL;
907
+
908
+ g_iRefAll--;
909
+ if( g_iRefAll == 0 )
910
+ {
911
+ CoUninitialize();
912
+ }
913
+ }
914
+
915
+ #ifdef DXRUBY_USE_TYPEDDATA
916
+ const rb_data_type_t SoundEffect_data_type = {
917
+ "SoundEffect",
918
+ {
919
+ 0,
920
+ SoundEffect_release,
921
+ 0,
922
+ },
923
+ NULL, NULL
924
+ };
925
+ #endif
926
+
927
+ /*--------------------------------------------------------------------
928
+ SoundEffect�N���X��dispose�B
929
+ ---------------------------------------------------------------------*/
930
+ static VALUE SoundEffect_dispose( VALUE self )
931
+ {
932
+ struct DXRubySoundEffect *soundeffect = DXRUBY_GET_STRUCT( SoundEffect, self );
933
+ DXRUBY_CHECK_DISPOSE( soundeffect, pDSBuffer );
934
+ SoundEffect_free( soundeffect );
935
+ return self;
936
+ }
937
+
938
+ /*--------------------------------------------------------------------
939
+ SoundEffect�N���X��disposed?�B
940
+ ---------------------------------------------------------------------*/
941
+ static VALUE SoundEffect_check_disposed( VALUE self )
942
+ {
943
+ if( DXRUBY_GET_STRUCT( SoundEffect, self )->pDSBuffer == NULL )
944
+ {
945
+ return Qtrue;
946
+ }
947
+
948
+ return Qfalse;
949
+ }
950
+
951
+ /*--------------------------------------------------------------------
952
+ SoundEffect�N���X��allocate�B���������m�ۂ���ׂ�initialize�O�ɌĂ΂��B
953
+ ---------------------------------------------------------------------*/
954
+ static VALUE SoundEffect_allocate( VALUE klass )
955
+ {
956
+ VALUE obj;
957
+ struct DXRubySoundEffect *soundeffect;
958
+
959
+ /* DXRubySoundEffect�̃������擾��SoundEffect�I�u�W�F�N�g���� */
960
+ soundeffect = malloc(sizeof(struct DXRubySoundEffect));
961
+ if( soundeffect == NULL ) rb_raise( eDXRubyError, "Out of memory - SoundEffect_allocate" );
962
+ #ifdef DXRUBY_USE_TYPEDDATA
963
+ obj = TypedData_Wrap_Struct( klass, &SoundEffect_data_type, soundeffect );
964
+ #else
965
+ obj = Data_Wrap_Struct(klass, 0, SoundEffect_release, soundeffect);
966
+ #endif
967
+
968
+ /* �Ƃ肠�����T�E���h�I�u�W�F�N�g��NULL�ɂ��Ă��� */
969
+ soundeffect->pDSBuffer = NULL;
970
+
971
+ return obj;
972
+ }
973
+
974
+
975
+ static short calcwave(int type, double vol, double count, double p, double duty)
976
+ {
977
+ switch( type )
978
+ {
979
+ case 1: /* �T�C���g */
980
+ return (short)((sin( (3.141592653589793115997963468544185161590576171875f * 2) * (double)count / (double)p )) * (double)vol * 128);
981
+ break;
982
+ case 2: /* �m�R�M���g */
983
+ return (short)(((double)count / (double)p - 0.5) * (double)vol * 256);
984
+ break;
985
+ case 3: /* �O�p�g */
986
+ if( count < p / 4 ) /* 1/4 */
987
+ {
988
+ return (short)((double)count / ((double)p / 4) * (double)vol * 128);
989
+ }
990
+ else if( count < p / 2 ) /* 2/4 */
991
+ {
992
+ return (short)(((double)p / 2 - (double)count) / ((double)p / 4) * (double)vol * 128);
993
+ }
994
+ else if( count < p * 3 / 4 ) /* 3/4 */
995
+ {
996
+ return (short)(-((double)count - (double)p / 2)/ ((double)p / 4) * (double)vol * 128);
997
+ }
998
+ else /* �Ō� */
999
+ {
1000
+ return (short)(-((double)p - (double)count) / ((double)p / 4) * (double)vol * 128);
1001
+ }
1002
+ break;
1003
+ case 0: /* ��`�g */
1004
+ default: /* �f�t�H���g */
1005
+ if( count < p * duty ) /* �O�� */
1006
+ {
1007
+ return (short)(vol * 128);
1008
+ }
1009
+ else /* �㔼 */
1010
+ {
1011
+ return (short)(-vol * 128);
1012
+ }
1013
+ break;
1014
+ }
1015
+ }
1016
+
1017
+
1018
+ /*--------------------------------------------------------------------
1019
+ SoundEffect�N���X��initialize�B�g�`�𐶐�����B
1020
+ ---------------------------------------------------------------------*/
1021
+ static VALUE SoundEffect_initialize( int argc, VALUE *argv, VALUE obj )
1022
+ {
1023
+ HRESULT hr;
1024
+ struct DXRubySoundEffect *soundeffect;
1025
+ DSBUFFERDESC desc;
1026
+ WAVEFORMATEX pcmwf;
1027
+ int i;
1028
+ short *pointer, *pointer2;
1029
+ DWORD size, size2;
1030
+ VALUE vf;
1031
+ double count, duty = 0.5;
1032
+ double vol;
1033
+ double f;
1034
+ VALUE vsize, vtype, vresolution;
1035
+ int type, resolution;
1036
+
1037
+ g_iRefAll++;
1038
+
1039
+ rb_scan_args( argc, argv, "12", &vsize, &vtype, &vresolution );
1040
+
1041
+ type = vtype == Qnil ? 0 : NUM2INT( vtype );
1042
+ resolution = vresolution == Qnil ? 1000 : (NUM2INT( vresolution ) > 44100 ? 44100 : NUM2INT( vresolution ));
1043
+
1044
+ /* DirectSound�I�u�W�F�N�g�̍쐬 */
1045
+ if( g_iRefDS == 0 )
1046
+ {
1047
+ hr = DirectSoundCreate8( &DSDEVID_DefaultPlayback, &g_pDSound, NULL );
1048
+ if( FAILED( hr ) )
1049
+ {
1050
+ rb_raise( eDXRubyError, "DirectSound initialize error - DirectSoundCreate8" );
1051
+ }
1052
+
1053
+ hr = g_pDSound->lpVtbl->SetCooperativeLevel( g_pDSound, g_hWnd, DSSCL_PRIORITY );
1054
+ if( FAILED( hr ) )
1055
+ {
1056
+ rb_raise( eDXRubyError, "DirectSound initialize error - SetCooperativeLevel" );
1057
+ }
1058
+ }
1059
+ g_iRefDS++;
1060
+
1061
+ /* �T�E���h�I�u�W�F�N�g�쐬 */
1062
+ soundeffect = DXRUBY_GET_STRUCT( SoundEffect, obj );
1063
+ if( soundeffect->pDSBuffer )
1064
+ {
1065
+ g_iRefDS++;
1066
+ SoundEffect_free( soundeffect );
1067
+ g_iRefDS--;
1068
+ g_iRefAll++;
1069
+ }
1070
+
1071
+ /* �T�E���h�o�b�t�@�쐬 */
1072
+ pcmwf.wFormatTag = WAVE_FORMAT_PCM;
1073
+ pcmwf.nChannels = 1;
1074
+ pcmwf.nSamplesPerSec = 44100;
1075
+ pcmwf.wBitsPerSample = 16;
1076
+ pcmwf.nBlockAlign = pcmwf.nChannels * pcmwf.wBitsPerSample / 8;
1077
+ pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
1078
+ pcmwf.cbSize = 0;
1079
+
1080
+ desc.dwSize = sizeof(desc);
1081
+ desc.dwFlags = DSBCAPS_GLOBALFOCUS;
1082
+ #ifdef DXRUBY15
1083
+ if( TYPE( vsize ) == T_ARRAY )
1084
+ {
1085
+ desc.dwBufferBytes = RARRAY_LEN( vsize ) * (pcmwf.nChannels * pcmwf.wBitsPerSample / 8);
1086
+ }
1087
+ else
1088
+ {
1089
+ #endif
1090
+ desc.dwBufferBytes = pcmwf.nAvgBytesPerSec / 100 * NUM2INT(vsize) / 10;
1091
+ #ifdef DXRUBY15
1092
+ }
1093
+ #endif
1094
+ desc.dwReserved = 0;
1095
+ desc.lpwfxFormat = &pcmwf;
1096
+ desc.guid3DAlgorithm = DS3DALG_DEFAULT;
1097
+
1098
+ hr = g_pDSound->lpVtbl->CreateSoundBuffer( g_pDSound, &desc, &soundeffect->pDSBuffer, NULL );
1099
+
1100
+ if( FAILED( hr ) )
1101
+ {
1102
+ rb_raise( eDXRubyError, "Failure to create the SoundBuffer - CreateSoundBuffer" );
1103
+ }
1104
+
1105
+ /* ���b�N */
1106
+ hr = soundeffect->pDSBuffer->lpVtbl->Lock( soundeffect->pDSBuffer, 0, 0, &pointer, &size, &pointer2, &size2, DSBLOCK_ENTIREBUFFER );
1107
+ if( FAILED( hr ) || size2 != 0 )
1108
+ {
1109
+ rb_raise( eDXRubyError, "Failure to lock the SoundBuffer - Lock" );
1110
+ }
1111
+
1112
+ if( TYPE( vsize ) == T_ARRAY )
1113
+ {
1114
+ /* ���o�b�t�@���� */
1115
+ for( i = 0; i < desc.dwBufferBytes / (pcmwf.wBitsPerSample / 8); i++ )
1116
+ {
1117
+ double tmp = NUM2DBL( RARRAY_AREF( vsize, i ) );
1118
+ if( tmp < 0.0 )
1119
+ {
1120
+ if( tmp < -1.0 ) tmp = -1.0;
1121
+ pointer[i] = (short)(tmp * 32768.0);
1122
+ }
1123
+ else
1124
+ {
1125
+ if( tmp > 1.0 ) tmp = 1.0;
1126
+ pointer[i] = (short)(tmp * 32767.0);
1127
+ }
1128
+ }
1129
+ }
1130
+ else
1131
+ {
1132
+ /* ���o�b�t�@������ */
1133
+ for( i = 0; i < desc.dwBufferBytes / (pcmwf.wBitsPerSample / 8); i++ )
1134
+ {
1135
+ pointer[i] = 0;
1136
+ }
1137
+
1138
+ count = 0;
1139
+
1140
+ /* �g�`���� */
1141
+ for( i = 0; i < desc.dwBufferBytes / (pcmwf.wBitsPerSample / 8); i++ )
1142
+ {
1143
+ /* �w�莞�ԒP�ʂŃu���b�N���Ăяo�� */
1144
+ if ( i % (pcmwf.nSamplesPerSec / resolution) == 0 )
1145
+ {
1146
+ vf = rb_yield( obj );
1147
+ if( TYPE( vf ) != T_ARRAY )
1148
+ {
1149
+ soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
1150
+ rb_raise(rb_eTypeError, "invalid value - SoundEffect_initialize");
1151
+ break;
1152
+ }
1153
+ f = NUM2DBL( rb_ary_entry(vf, 0) );
1154
+ vol = NUM2DBL(rb_ary_entry(vf, 1));
1155
+ if( RARRAY_LEN( vf ) > 2 )
1156
+ {
1157
+ duty = NUM2DBL(rb_ary_entry(vf, 2));
1158
+ }
1159
+ /* �ő�/�Œ���g���ƍő�{�����[���̐��� */
1160
+ f = f > pcmwf.nSamplesPerSec / 2.0f ? pcmwf.nSamplesPerSec / 2.0f : f;
1161
+ f = f < 20 ? 20 : f;
1162
+ vol = vol > 255 ? 255 : vol;
1163
+ vol = vol < 0 ? 0 : vol;
1164
+ }
1165
+ count = count + f;
1166
+ if( count >= pcmwf.nSamplesPerSec )
1167
+ {
1168
+ count = count - pcmwf.nSamplesPerSec;
1169
+ }
1170
+ pointer[i] = calcwave(type, vol, count, pcmwf.nSamplesPerSec, duty);
1171
+ }
1172
+ }
1173
+
1174
+ /* �A�����b�N */
1175
+ hr = soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
1176
+ if( FAILED( hr ) )
1177
+ {
1178
+ rb_raise( eDXRubyError, "Failure to lock the SoundBuffer - Lock" );
1179
+ }
1180
+
1181
+ return obj;
1182
+
1183
+ }
1184
+
1185
+
1186
+ /*--------------------------------------------------------------------
1187
+ �g�`����������B
1188
+ ---------------------------------------------------------------------*/
1189
+ static VALUE SoundEffect_add( int argc, VALUE *argv, VALUE obj )
1190
+ {
1191
+ HRESULT hr;
1192
+ struct DXRubySoundEffect *soundeffect;
1193
+ DSBUFFERDESC desc;
1194
+ WAVEFORMATEX pcmwf;
1195
+ int i;
1196
+ short *pointer, *pointer2;
1197
+ DWORD size, size2;
1198
+ VALUE vf, vtype, vresolution;
1199
+ double count, duty = 0.5;
1200
+ double vol;
1201
+ double f;
1202
+ int type, resolution;
1203
+ int data;
1204
+
1205
+ rb_scan_args( argc, argv, "02", &vtype, &vresolution );
1206
+
1207
+ type = vtype == Qnil ? 0 : NUM2INT( vtype );
1208
+ resolution = vresolution == Qnil ? 1000 : (NUM2INT( vresolution ) > 44100 ? 44100 : NUM2INT( vresolution ));
1209
+
1210
+ /* �T�E���h�I�u�W�F�N�g�擾 */
1211
+ soundeffect = DXRUBY_GET_STRUCT( SoundEffect, obj );
1212
+ DXRUBY_CHECK_DISPOSE( soundeffect, pDSBuffer );
1213
+
1214
+ /* ���b�N */
1215
+ hr = soundeffect->pDSBuffer->lpVtbl->Lock( soundeffect->pDSBuffer, 0, 0, &pointer, &size, &pointer2, &size2, DSBLOCK_ENTIREBUFFER );
1216
+ if( FAILED( hr ) || size2 != 0 )
1217
+ {
1218
+ rb_raise( eDXRubyError, "Failure to lock the SoundBuffer - Lock" );
1219
+ }
1220
+
1221
+ pcmwf.nChannels = 1;
1222
+ pcmwf.nSamplesPerSec = 44100;
1223
+ pcmwf.wBitsPerSample = 16;
1224
+ pcmwf.nBlockAlign = pcmwf.nChannels * pcmwf.wBitsPerSample / 8;
1225
+ pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
1226
+ desc.dwBufferBytes = size;
1227
+
1228
+ count = 0;
1229
+
1230
+ /* �g�`���� */
1231
+ for( i = 0; i < desc.dwBufferBytes / (pcmwf.wBitsPerSample / 8); i++ )
1232
+ {
1233
+ /* �w�莞�ԒP�ʂŃu���b�N���Ăяo�� */
1234
+ if ( i % (pcmwf.nSamplesPerSec / resolution) == 0 )
1235
+ {
1236
+ vf = rb_yield( obj );
1237
+ if( TYPE( vf ) != T_ARRAY )
1238
+ {
1239
+ soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
1240
+ rb_raise(rb_eTypeError, "invalid value - SoundEffect_add");
1241
+ break;
1242
+ }
1243
+ f = NUM2DBL( rb_ary_entry(vf, 0) );
1244
+ vol = NUM2DBL(rb_ary_entry(vf, 1));
1245
+ if( RARRAY_LEN( vf ) > 2 )
1246
+ {
1247
+ duty = NUM2DBL(rb_ary_entry(vf, 2));
1248
+ }
1249
+ /* �ő�/�Œ���g���ƍő�{�����[���̐��� */
1250
+ f = f > pcmwf.nSamplesPerSec / 2.0f ? pcmwf.nSamplesPerSec / 2.0f : f;
1251
+ f = f < 20 ? 20 : f;
1252
+ vol = vol > 255 ? 255 : vol;
1253
+ vol = vol < 0 ? 0 : vol;
1254
+ }
1255
+ count = count + f;
1256
+ if( count >= pcmwf.nSamplesPerSec )
1257
+ {
1258
+ count = count - pcmwf.nSamplesPerSec;
1259
+ }
1260
+
1261
+ data = calcwave(type, vol, count, pcmwf.nSamplesPerSec, duty);
1262
+
1263
+ if( data + (int)pointer[i] > 32767 )
1264
+ {
1265
+ pointer[i] = 32767;
1266
+ }
1267
+ else if( data + (int)pointer[i] < -32768 )
1268
+ {
1269
+ pointer[i] = -32768;
1270
+ }
1271
+ else
1272
+ {
1273
+ pointer[i] += data;
1274
+ }
1275
+ }
1276
+
1277
+ /* �A�����b�N */
1278
+ hr = soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
1279
+ if( FAILED( hr ) )
1280
+ {
1281
+ rb_raise( eDXRubyError, "Failure to lock the SoundBuffer - Lock" );
1282
+ }
1283
+
1284
+ return obj;
1285
+
1286
+ }
1287
+
1288
+
1289
+ /*--------------------------------------------------------------------
1290
+ ����‚炷
1291
+ ---------------------------------------------------------------------*/
1292
+ static VALUE SoundEffect_play( int argc, VALUE *argv, VALUE self )
1293
+ {
1294
+ HRESULT hr;
1295
+ struct DXRubySoundEffect *se = DXRUBY_GET_STRUCT( SoundEffect, self );
1296
+ VALUE vflag;
1297
+ DXRUBY_CHECK_DISPOSE( se, pDSBuffer );
1298
+
1299
+ rb_scan_args( argc, argv, "01", &vflag );
1300
+
1301
+ /* �Ƃ߂� */
1302
+ hr = se->pDSBuffer->lpVtbl->Stop( se->pDSBuffer );
1303
+ if( FAILED( hr ) )
1304
+ {
1305
+ rb_raise( eDXRubyError, "Sound play failed - SoundEffect_play" );
1306
+ }
1307
+
1308
+ hr = se->pDSBuffer->lpVtbl->SetCurrentPosition( se->pDSBuffer, 0 );
1309
+ if( FAILED( hr ) )
1310
+ {
1311
+ rb_raise( eDXRubyError, "Sound play failed - SoundEffect_play" );
1312
+ }
1313
+
1314
+ /* �� */
1315
+ hr = se->pDSBuffer->lpVtbl->Play( se->pDSBuffer, 0, 0, RTEST(vflag) ? DSBPLAY_LOOPING : 0 );
1316
+ if( FAILED( hr ) )
1317
+ {
1318
+ rb_raise( eDXRubyError, "Sound play failed - SoundEffect_play" );
1319
+ }
1320
+ return self;
1321
+ }
1322
+
1323
+
1324
+ /*--------------------------------------------------------------------
1325
+ �����~�߂�
1326
+ ---------------------------------------------------------------------*/
1327
+ static VALUE SoundEffect_stop( VALUE obj )
1328
+ {
1329
+ HRESULT hr;
1330
+ struct DXRubySoundEffect *soundeffect;
1331
+
1332
+ soundeffect = DXRUBY_GET_STRUCT( SoundEffect, obj );
1333
+ DXRUBY_CHECK_DISPOSE( soundeffect, pDSBuffer );
1334
+
1335
+ /* �Ƃ߂� */
1336
+ hr = soundeffect->pDSBuffer->lpVtbl->Stop( soundeffect->pDSBuffer );
1337
+ if( FAILED( hr ) )
1338
+ {
1339
+ rb_raise( eDXRubyError, "���̒�~�Ɏ��s���܂��� - Stop" );
1340
+ }
1341
+
1342
+ return obj;
1343
+ }
1344
+
1345
+
1346
+ /*--------------------------------------------------------------------
1347
+ wav�t�@�C���o��
1348
+ ---------------------------------------------------------------------*/
1349
+ static VALUE SoundEffect_save( VALUE self, VALUE vfilename )
1350
+ {
1351
+ HRESULT hr;
1352
+ HANDLE hfile;
1353
+ short *pointer, *pointer2;
1354
+ DWORD size, size2;
1355
+ DWORD tmpl;
1356
+ WORD tmps;
1357
+ DWORD wsize;
1358
+ struct DXRubySoundEffect *se = DXRUBY_GET_STRUCT( SoundEffect, self );
1359
+
1360
+ DXRUBY_CHECK_DISPOSE( se, pDSBuffer );
1361
+
1362
+ /* ���b�N */
1363
+ hr = se->pDSBuffer->lpVtbl->Lock( se->pDSBuffer, 0, 0, &pointer, &size, &pointer2, &size2, DSBLOCK_ENTIREBUFFER );
1364
+ if( FAILED( hr ) || size2 != 0 )
1365
+ {
1366
+ rb_raise( eDXRubyError, "Failure to lock the SoundBuffer - Lock" );
1367
+ }
1368
+
1369
+ hfile = CreateFile( RSTRING_PTR( vfilename ), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1370
+ if( hfile == INVALID_HANDLE_VALUE )
1371
+ {
1372
+ rb_raise( eDXRubyError, "Write failure - open" );
1373
+ }
1374
+
1375
+ if( !WriteFile( hfile, "RIFF", 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1376
+ tmpl = size + 44 - 8;
1377
+ if( !WriteFile( hfile, &tmpl, 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1378
+ if( !WriteFile( hfile, "WAVE", 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1379
+ if( !WriteFile( hfile, "fmt ", 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1380
+ tmpl = 16;
1381
+ if( !WriteFile( hfile, &tmpl, 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1382
+ tmps = 1;
1383
+ if( !WriteFile( hfile, &tmps, 2, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1384
+ tmps = 1;
1385
+ if( !WriteFile( hfile, &tmps, 2, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1386
+ tmpl = 44100;
1387
+ if( !WriteFile( hfile, &tmpl, 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1388
+ tmpl = 44100*2;
1389
+ if( !WriteFile( hfile, &tmpl, 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1390
+ tmps = 2;
1391
+ if( !WriteFile( hfile, &tmps, 2, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1392
+ tmps = 16;
1393
+ if( !WriteFile( hfile, &tmps, 2, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1394
+
1395
+ if( !WriteFile( hfile, "data", 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1396
+ tmpl = size;
1397
+ if( !WriteFile( hfile, &tmpl, 4, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1398
+ if( !WriteFile( hfile, pointer, size, &wsize, NULL ) ) rb_raise( eDXRubyError, "Write failure - write" );
1399
+
1400
+ CloseHandle( hfile );
1401
+
1402
+ /* �A�����b�N */
1403
+ hr = se->pDSBuffer->lpVtbl->Unlock( se->pDSBuffer, pointer, size, pointer2, size2 );
1404
+ if( FAILED( hr ) )
1405
+ {
1406
+ rb_raise( eDXRubyError, "Failure to lock the SoundBuffer - Lock" );
1407
+ }
1408
+
1409
+ return self;
1410
+ }
1411
+
1412
+
1413
+ /*--------------------------------------------------------------------
1414
+ �z��
1415
+ ---------------------------------------------------------------------*/
1416
+ static VALUE SoundEffect_to_a( VALUE self )
1417
+ {
1418
+ HRESULT hr;
1419
+ short *pointer, *pointer2;
1420
+ DWORD size, size2;
1421
+ struct DXRubySoundEffect *se = DXRUBY_GET_STRUCT( SoundEffect, self );
1422
+ VALUE ary;
1423
+ int i;
1424
+
1425
+ DXRUBY_CHECK_DISPOSE( se, pDSBuffer );
1426
+
1427
+ /* ���b�N */
1428
+ hr = se->pDSBuffer->lpVtbl->Lock( se->pDSBuffer, 0, 0, &pointer, &size, &pointer2, &size2, DSBLOCK_ENTIREBUFFER );
1429
+ if( FAILED( hr ) || size2 != 0 )
1430
+ {
1431
+ rb_raise( eDXRubyError, "Failure to lock the SoundBuffer - Lock" );
1432
+ }
1433
+
1434
+ ary = rb_ary_new2( size / 2 );
1435
+ for( i = 0; i < size / 2; i++ )
1436
+ {
1437
+ double tmp;
1438
+ if( pointer[i] < 0 )
1439
+ {
1440
+ tmp = pointer[i] / 32768.0;
1441
+ }
1442
+ else
1443
+ {
1444
+ tmp = pointer[i] / 32767.0;
1445
+ }
1446
+ rb_ary_push( ary, rb_float_new( tmp ) );
1447
+ }
1448
+
1449
+ /* �A�����b�N */
1450
+ hr = se->pDSBuffer->lpVtbl->Unlock( se->pDSBuffer, pointer, size, pointer2, size2 );
1451
+ if( FAILED( hr ) )
1452
+ {
1453
+ rb_raise( eDXRubyError, "Failure to lock the SoundBuffer - Lock" );
1454
+ }
1455
+
1456
+ return ary;
1457
+ }
1458
+
1459
+
1460
+ void Init_dxruby_Sound( void )
1461
+ {
1462
+ /* Sound�N���X��` */
1463
+ cSound = rb_define_class_under( mDXRuby, "Sound", rb_cObject );
1464
+ rb_define_singleton_method( cSound, "load_from_memory", Sound_load_from_memory, 2 );
1465
+ rb_define_singleton_method( cSound, "loadFromMemory", Sound_load_from_memory, 2 );
1466
+
1467
+ /* Sound�N���X�Ƀ��\�b�h�o�^*/
1468
+ rb_define_private_method( cSound, "initialize" , Sound_initialize , 1 );
1469
+ rb_define_method( cSound, "dispose" , Sound_dispose , 0 );
1470
+ rb_define_method( cSound, "disposed?" , Sound_check_disposed, 0 );
1471
+ rb_define_method( cSound, "play" , Sound_play , 0 );
1472
+ rb_define_method( cSound, "stop" , Sound_stop , 0 );
1473
+ rb_define_method( cSound, "set_volume" , Sound_setVolume , -1 );
1474
+ rb_define_method( cSound, "setVolume" , Sound_setVolume , -1 );
1475
+ rb_define_method( cSound, "pan" , Sound_getPan , 0 );
1476
+ rb_define_method( cSound, "pan=" , Sound_setPan , 1 );
1477
+ rb_define_method( cSound, "frequency" , Sound_getFrequency , 0 );
1478
+ rb_define_method( cSound, "frequency=" , Sound_setFrequency , 1 );
1479
+ rb_define_method( cSound, "start=" , Sound_setStart , 1 );
1480
+ rb_define_method( cSound, "loop_start=" , Sound_setLoopStart , 1 );
1481
+ rb_define_method( cSound, "loopStart=" , Sound_setLoopStart , 1 );
1482
+ rb_define_method( cSound, "loop_end=" , Sound_setLoopEnd , 1 );
1483
+ rb_define_method( cSound, "loopEnd=" , Sound_setLoopEnd , 1 );
1484
+ rb_define_method( cSound, "loop_count=" , Sound_setLoopCount , 1 );
1485
+ rb_define_method( cSound, "loopCount=" , Sound_setLoopCount , 1 );
1486
+
1487
+ /* Sound�I�u�W�F�N�g�𐶐���������initialize�̑O�ɌĂ΂�郁�������蓖�Ċ֐��o�^ */
1488
+ rb_define_alloc_func( cSound, Sound_allocate );
1489
+
1490
+
1491
+ /* SoundEffect�N���X��` */
1492
+ cSoundEffect = rb_define_class_under( mDXRuby, "SoundEffect", rb_cObject );
1493
+
1494
+ /* SoundEffect�N���X�Ƀ��\�b�h�o�^*/
1495
+ rb_define_private_method( cSoundEffect, "initialize", SoundEffect_initialize, -1 );
1496
+ rb_define_method( cSoundEffect, "dispose" , SoundEffect_dispose , 0 );
1497
+ rb_define_method( cSoundEffect, "disposed?" , SoundEffect_check_disposed, 0 );
1498
+ rb_define_method( cSoundEffect, "play" , SoundEffect_play , -1 );
1499
+ rb_define_method( cSoundEffect, "stop" , SoundEffect_stop , 0 );
1500
+ rb_define_method( cSoundEffect, "add" , SoundEffect_add , -1 );
1501
+ rb_define_method( cSoundEffect, "save" , SoundEffect_save , 1 );
1502
+ #ifdef DXRUBY15
1503
+ rb_define_method( cSoundEffect, "to_a" , SoundEffect_to_a , 0 );
1504
+ #endif
1505
+ /* SoundEffect�I�u�W�F�N�g�𐶐���������initialize�̑O�ɌĂ΂�郁�������蓖�Ċ֐��o�^ */
1506
+ rb_define_alloc_func( cSoundEffect, SoundEffect_allocate );
1507
+
1508
+ rb_define_const( mDXRuby, "WAVE_SIN" , INT2FIX(WAVE_SIN) );
1509
+ rb_define_const( mDXRuby, "WAVE_SAW" , INT2FIX(WAVE_SAW) );
1510
+ rb_define_const( mDXRuby, "WAVE_TRI" , INT2FIX(WAVE_TRI) );
1511
+ rb_define_const( mDXRuby, "WAVE_RECT" , INT2FIX(WAVE_RECT) );
1512
+
1513
+ rb_define_const( mDXRuby, "TYPE_MIDI" , INT2FIX(0) );
1514
+ rb_define_const( mDXRuby, "TYPE_WAV" , INT2FIX(1) );
1515
+ }
1516
+