dxrubynd 1.4.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+