Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libjsound/DirectAudioDevice.c
41149 views
1
/*
2
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
/* TODO:
27
* - move all the conversion code into an own file
28
*/
29
30
//#define USE_TRACE
31
//#define USE_ERROR
32
33
34
#include <jni.h>
35
#include <jni_util.h>
36
// for malloc
37
#ifdef _ALLBSD_SOURCE
38
#include <stdlib.h>
39
#else
40
#include <malloc.h>
41
#endif
42
#include "SoundDefs.h"
43
#include "DirectAudio.h"
44
#include "Utilities.h"
45
#include "com_sun_media_sound_DirectAudioDevice.h"
46
47
48
typedef struct {
49
void* handle;
50
int encoding;
51
int sampleSizeInBits;
52
int frameSize;
53
int channels;
54
int isSigned;
55
int isBigEndian;
56
UINT8* conversionBuffer;
57
int conversionBufferSize;
58
} DAUDIO_Info;
59
60
61
//////////////////////////////////////////// MAP Conversion stuff /////////////////////////////////
62
63
/* 16 bit signed sample, native endianness, stored in 32-bits */
64
typedef INT32 MAP_Sample;
65
66
static INLINE UINT16 MAP_SWAP16_impl(UINT16 a) {
67
return (a>>8) | (a<<8);
68
}
69
70
static INLINE UINT32 MAP_SWAP32_impl(UINT32 a) {
71
return (a>>24)
72
| ((a>>8) & 0xFF00)
73
| ((a<<8) & 0xFF0000)
74
| (a<<24);
75
}
76
77
static INLINE UINT32 MAP_SWAP16BIT(UINT32 sh) {
78
return (UINT32) ((sh & 0xFF) << 8) | ((sh & 0xFF00) >> 8);
79
}
80
81
static INLINE INT32 MAP_ClipAndConvertToShort(MAP_Sample sample) {
82
if (sample < -32768) {
83
return -32768;
84
}
85
else if (sample > 32767) {
86
return 32767;
87
}
88
return (INT32) sample;
89
}
90
91
92
static INLINE INT32 MAP_ClipAndConvertToShort_Swapped(MAP_Sample sample) {
93
if (sample < -32768) {
94
return 0x0080;
95
}
96
else if (sample > 32767) {
97
return 0xFF7F;
98
}
99
return (INT32) (INT16) MAP_SWAP16BIT(sample);
100
}
101
102
static INLINE INT8 MAP_ClipAndConvertToByte(MAP_Sample sample) {
103
if (sample < -32768) {
104
return -128;
105
}
106
else if (sample > 32767) {
107
return 127;
108
}
109
return (INT8) (sample >> 8);
110
}
111
112
113
static INLINE UINT8 MAP_ClipAndConvertToUByte(MAP_Sample sample) {
114
if (sample < -32768) {
115
return 0;
116
}
117
else if (sample > 32767) {
118
return 255;
119
}
120
return (UINT8) ((sample >> 8) + 128);
121
}
122
123
/* conversion from/to 16 bit signed little endian to native endian samples */
124
#ifdef _LITTLE_ENDIAN
125
#define MAP_LE_SHORT2SAMPLE(sh) ((MAP_Sample) (sh))
126
#define MAP_SAMPLE2LE_SHORT(sample) (sample)
127
#define MAP_SAMPLE2LE_SHORT_CLIP(sample) MAP_ClipAndConvertToShort(sample)
128
#else
129
#define MAP_LE_SHORT2SAMPLE(sh) ((MAP_Sample) (INT16) MAP_SWAP16BIT(sh))
130
#define MAP_SAMPLE2LE_SHORT(sample) (INT16) MAP_SWAP16BIT(sample)
131
#define MAP_SAMPLE2LE_SHORT_CLIP(sample) MAP_ClipAndConvertToShort_Swapped(sample)
132
#endif
133
134
/* conversion from/to 16 bit signed big endian to native endian samples */
135
#ifndef _LITTLE_ENDIAN
136
#define MAP_BE_SHORT2SAMPLE(sh) ((MAP_Sample) (sh))
137
#define MAP_SAMPLE2BE_SHORT(sample) (sample)
138
#define MAP_SAMPLE2BE_SHORT_CLIP(sample) MAP_ClipAndConvertToShort(sample)
139
#else
140
#define MAP_BE_SHORT2SAMPLE(sh) ((MAP_Sample) (INT16) MAP_SWAP16BIT(sh))
141
#define MAP_SAMPLE2BE_SHORT(sample) ((INT16) MAP_SWAP16BIT(sample))
142
#define MAP_SAMPLE2BE_SHORT_CLIP(sample) MAP_ClipAndConvertToShort_Swapped(sample)
143
#endif
144
145
/* conversion from/to 8 bit samples */
146
#define MAP_INT82SAMPLE(by) ((MAP_Sample) (((INT32) ((INT8) (by))) << 8))
147
#define MAP_UINT82SAMPLE(by) ((MAP_Sample) (((INT32) ((UINT8) (by) - 128)) << 8))
148
#define MAP_SAMPLE2UINT8(sample) ((UINT8) ((((MAP_Sample) (sample)) >> 8) + 128))
149
#define MAP_SAMPLE2INT8(sample) ((INT8) (((MAP_Sample) (sample)) >> 8))
150
#define MAP_SAMPLE2UINT8_CLIP(sample) MAP_ClipAndConvertToUByte(sample)
151
#define MAP_SAMPLE2INT8_CLIP(sample) MAP_ClipAndConvertToByte(sample)
152
153
/* macros for endian conversion */
154
#ifdef _LITTLE_ENDIAN
155
#define MAP_NATIVE2LE16(a) (a)
156
#define MAP_NATIVE2BE16(a) MAP_SWAP16_impl(a)
157
#define MAP_NATIVE2LE32(a) (a)
158
#define MAP_NATIVE2BE32(a) MAP_SWAP32_impl(a)
159
#else
160
#define MAP_NATIVE2LE16(a) MAP_SWAP16_impl(a)
161
#define MAP_NATIVE2BE16(a) (a)
162
#define MAP_NATIVE2LE32(a) MAP_SWAP32_impl(a)
163
#define MAP_NATIVE2BE32(a) (a)
164
#endif
165
#define MAP_LE2NATIVE16(a) MAP_NATIVE2LE16(a)
166
#define MAP_BE2NATIVE16(a) MAP_NATIVE2BE16(a)
167
#define MAP_LE2NATIVE32(a) MAP_NATIVE2LE32(a)
168
#define MAP_BE2NATIVE32(a) MAP_NATIVE2BE32(a)
169
170
171
////////////////////////////// Utility function /////////////////////////////////
172
173
/*
174
* conversion of this buffer:
175
* conversion size=1 -> each byte is converted from signed to unsigned or vice versa
176
* conversion size=2,3,4: the order of bytes in a sample is reversed (endianness)
177
* for sign conversion of a 24-bit sample stored in 32bits, 4 should be passed
178
* as conversionSize
179
*/
180
void handleSignEndianConversion(INT8* data, INT8* output, int byteSize, int conversionSize) {
181
TRACE1("conversion with size %d\n", conversionSize);
182
switch (conversionSize) {
183
case 1: {
184
while (byteSize > 0) {
185
*output = *data + (char) 128; // use wrap-around
186
byteSize--;
187
data++;
188
output++;
189
}
190
break;
191
}
192
case 2: {
193
INT8 h;
194
byteSize = byteSize / 2;
195
while (byteSize > 0) {
196
h = *data;
197
data++;
198
*output = *data;
199
output++;
200
*output = h;
201
byteSize--;
202
data++; output++;
203
}
204
break;
205
}
206
case 3: {
207
INT8 h;
208
byteSize = byteSize / 3;
209
while (byteSize > 0) {
210
h = *data;
211
*output = data[2];
212
data++; output++;
213
*output = *data;
214
data++; output++;
215
*output = h;
216
data++; output++;
217
byteSize--;
218
}
219
break;
220
}
221
case 4: {
222
INT8 h1, h2;
223
byteSize = byteSize / 4;
224
while (byteSize > 0) {
225
h1 = data[0];
226
h2 = data[1];
227
*output = data[3]; output++;
228
*output = data[2]; output++;
229
*output = h2; output++;
230
*output = h1; output++;
231
data += 4;
232
byteSize--;
233
}
234
break;
235
}
236
default:
237
ERROR1("DirectAudioDevice.c: wrong conversionSize %d!\n", conversionSize);
238
}
239
}
240
241
/* aply the gain to one sample */
242
#define CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, FROM_SAMPLE, FACTOR) \
243
/* convert to MAP_Sample native type */ \
244
sample = TO_SAMPLE(*INPUT); \
245
/* apply gain */ \
246
sample = (MAP_Sample) (sample * FACTOR); \
247
/* convert to output type */ \
248
(*OUTPUT) = FROM_SAMPLE(sample); \
249
INPUT++; OUTPUT++
250
251
252
/* macro for conversion of a mono block */
253
#define LOOP_M(INPUT, OUTPUT, TO_SAMPLE, FROM_SAMPLE, FROM_SAMPLE_CLIP) \
254
if (leftGain > 1.0) { \
255
for ( ; len > 0; --len) { \
256
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
257
FROM_SAMPLE_CLIP, leftGain); \
258
} \
259
} else { \
260
for ( ; len > 0; --len) { \
261
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
262
FROM_SAMPLE, leftGain); \
263
} \
264
} \
265
break
266
267
/* macro for conversion of a stereo block */
268
#define LOOP_S(INPUT, OUTPUT, TO_SAMPLE, FROM_SAMPLE, FROM_SAMPLE_CLIP) \
269
if (leftGain > 1.0) { \
270
if (rightGain > 1.0) { \
271
for ( ; len > 0; --len) { \
272
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
273
FROM_SAMPLE_CLIP, leftGain); \
274
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
275
FROM_SAMPLE_CLIP, rightGain); \
276
} \
277
} else { \
278
for ( ; len > 0; --len) { \
279
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
280
FROM_SAMPLE_CLIP, leftGain); \
281
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
282
FROM_SAMPLE, rightGain); \
283
} \
284
} \
285
} else { \
286
if (rightGain > 1.0) { \
287
for ( ; len > 0; --len) { \
288
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
289
FROM_SAMPLE, leftGain); \
290
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
291
FROM_SAMPLE_CLIP, rightGain); \
292
} \
293
} else { \
294
for ( ; len > 0; --len) { \
295
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
296
FROM_SAMPLE, leftGain); \
297
CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, \
298
FROM_SAMPLE, rightGain); \
299
} \
300
} \
301
} \
302
break
303
304
#define FORMAT2CODE(channels, bits, inSigned, outSigned, inBigEndian, outBigEndian) \
305
(channels << 20) \
306
| (bits << 4) \
307
| ((inSigned & 1) << 3) \
308
| ((outSigned & 1) << 2) \
309
| ((inBigEndian & 1) << 1) \
310
| (outBigEndian & 1)
311
312
#define FORMAT2CODE8(channels, inSigned, outSigned) \
313
FORMAT2CODE(channels, 8, inSigned, outSigned, 0, 0)
314
315
#define FORMAT2CODE16(channels, inBigEndian, outBigEndian) \
316
FORMAT2CODE(channels, 16, 1, 1, inBigEndian, outBigEndian)
317
318
319
void handleGainAndConversion(DAUDIO_Info* info, UINT8* input, UINT8* output,
320
int len, float leftGain, float rightGain,
321
int conversionSize) {
322
INT8* input8 = (INT8*) input;
323
INT8* output8 = (INT8*) output;
324
INT16* input16 = (INT16*) input;
325
INT16* output16 = (INT16*) output;
326
MAP_Sample sample;
327
328
int inIsSigned = info->isSigned;
329
int inIsBigEndian = info->isBigEndian;
330
if (conversionSize == 1) {
331
/* 8-bit conversion: change sign */
332
inIsSigned = !inIsSigned;
333
}
334
else if (conversionSize > 1) {
335
/* > 8-bit conversion: change endianness */
336
inIsBigEndian = !inIsBigEndian;
337
}
338
if (info->frameSize <= 0) {
339
ERROR1("DirectAudiODevice: invalid framesize=%d\n", info->frameSize);
340
return;
341
}
342
len /= info->frameSize;
343
TRACE3("handleGainAndConversion: len=%d frames, leftGain=%f, rightGain=%f, ",
344
len, leftGain, rightGain);
345
TRACE3("channels=%d, sampleSizeInBits=%d, frameSize=%d, ",
346
(int) info->channels, (int) info->sampleSizeInBits, (int) info->frameSize);
347
TRACE4("signed:%d -> %d, endian: %d -> %d",
348
(int) inIsSigned, (int) info->isSigned,
349
(int) inIsBigEndian, (int) info->isBigEndian);
350
TRACE1("convSize=%d\n", conversionSize);
351
352
switch (FORMAT2CODE(info->channels,
353
info->sampleSizeInBits,
354
inIsSigned,
355
info->isSigned,
356
inIsBigEndian,
357
info->isBigEndian)) {
358
/* 8-bit mono */
359
case FORMAT2CODE8(1, 0, 0):
360
LOOP_M(input8, output8, MAP_UINT82SAMPLE,
361
MAP_SAMPLE2UINT8, MAP_SAMPLE2UINT8_CLIP);
362
case FORMAT2CODE8(1, 0, 1):
363
LOOP_M(input8, output8, MAP_UINT82SAMPLE,
364
MAP_SAMPLE2INT8, MAP_SAMPLE2INT8_CLIP);
365
case FORMAT2CODE8(1, 1, 0):
366
LOOP_M(input8, output8, MAP_INT82SAMPLE,
367
MAP_SAMPLE2UINT8, MAP_SAMPLE2UINT8_CLIP);
368
case FORMAT2CODE8(1, 1, 1):
369
LOOP_M(input8, output8, MAP_INT82SAMPLE,
370
MAP_SAMPLE2INT8, MAP_SAMPLE2INT8_CLIP);
371
372
/* 8-bit stereo */
373
case FORMAT2CODE8(2, 0, 0):
374
LOOP_S(input8, output8, MAP_UINT82SAMPLE,
375
MAP_SAMPLE2UINT8, MAP_SAMPLE2UINT8_CLIP);
376
case FORMAT2CODE8(2, 0, 1):
377
LOOP_S(input8, output8, MAP_UINT82SAMPLE,
378
MAP_SAMPLE2INT8, MAP_SAMPLE2INT8_CLIP);
379
case FORMAT2CODE8(2, 1, 0):
380
LOOP_S(input8, output8, MAP_INT82SAMPLE,
381
MAP_SAMPLE2UINT8, MAP_SAMPLE2UINT8_CLIP);
382
case FORMAT2CODE8(2, 1, 1):
383
LOOP_S(input8, output8, MAP_INT82SAMPLE,
384
MAP_SAMPLE2INT8, MAP_SAMPLE2INT8_CLIP);
385
386
/* 16-bit mono (only signed is accepted) */
387
case FORMAT2CODE16(1, 0, 0):
388
LOOP_M(input16, output16, MAP_LE_SHORT2SAMPLE,
389
MAP_SAMPLE2LE_SHORT, MAP_SAMPLE2LE_SHORT_CLIP);
390
case FORMAT2CODE16(1, 0, 1):
391
LOOP_M(input16, output16, MAP_LE_SHORT2SAMPLE,
392
MAP_SAMPLE2BE_SHORT, MAP_SAMPLE2BE_SHORT_CLIP);
393
case FORMAT2CODE16(1, 1, 0):
394
LOOP_M(input16, output16, MAP_BE_SHORT2SAMPLE,
395
MAP_SAMPLE2LE_SHORT, MAP_SAMPLE2LE_SHORT_CLIP);
396
case FORMAT2CODE16(1, 1, 1):
397
LOOP_M(input16, output16, MAP_BE_SHORT2SAMPLE,
398
MAP_SAMPLE2BE_SHORT, MAP_SAMPLE2BE_SHORT_CLIP);
399
400
/* 16-bit stereo (only signed is accepted) */
401
case FORMAT2CODE16(2, 0, 0):
402
LOOP_S(input16, output16, MAP_LE_SHORT2SAMPLE,
403
MAP_SAMPLE2LE_SHORT, MAP_SAMPLE2LE_SHORT_CLIP);
404
case FORMAT2CODE16(2, 0, 1):
405
LOOP_S(input16, output16, MAP_LE_SHORT2SAMPLE,
406
MAP_SAMPLE2BE_SHORT, MAP_SAMPLE2BE_SHORT_CLIP);
407
case FORMAT2CODE16(2, 1, 0):
408
LOOP_S(input16, output16, MAP_BE_SHORT2SAMPLE,
409
MAP_SAMPLE2LE_SHORT, MAP_SAMPLE2LE_SHORT_CLIP);
410
case FORMAT2CODE16(2, 1, 1):
411
LOOP_S(input16, output16, MAP_BE_SHORT2SAMPLE,
412
MAP_SAMPLE2BE_SHORT, MAP_SAMPLE2BE_SHORT_CLIP);
413
414
default:
415
ERROR3("DirectAudioDevice: Cannot convert from native format: "
416
"bits=%d, inSigned=%d outSigned=%d, ",
417
(int) info->sampleSizeInBits,
418
(int) inIsSigned, (int) info->isSigned);
419
ERROR2("inBigEndian=%d, outBigEndian=%d\n",
420
(int) inIsBigEndian, (int) info->isBigEndian);
421
}
422
}
423
424
float ABS_VALUE(float a) {
425
return (a < 0)?-a:a;
426
}
427
428
429
//////////////////////////////////////////// DirectAudioDevice ////////////////////////////////////////////
430
431
/* ************************************** native control creation support ********************* */
432
433
// contains all the needed references so that the platform dependent code can call JNI wrapper functions
434
typedef struct tag_AddFormatCreator {
435
// general JNI variables
436
JNIEnv *env;
437
// the vector to be filled with the formats
438
jobject vector;
439
// the class containing the addFormat method
440
jclass directAudioDeviceClass;
441
// the method to be called to add the format
442
jmethodID addFormat; // signature (Ljava/util/Vector;IIFIBB)V
443
} AddFormatCreator;
444
445
void DAUDIO_AddAudioFormat(void* creatorV, int significantBits, int frameSizeInBytes,
446
int channels, float sampleRate,
447
int encoding, int isSigned,
448
int bigEndian) {
449
AddFormatCreator* creator = (AddFormatCreator*) creatorV;
450
if (frameSizeInBytes <= 0) {
451
if (channels > 0) {
452
frameSizeInBytes = ((significantBits + 7) / 8) * channels;
453
} else {
454
frameSizeInBytes = -1;
455
}
456
}
457
TRACE4("AddAudioFormat with sigBits=%d bits, frameSize=%d bytes, channels=%d, sampleRate=%d ",
458
significantBits, frameSizeInBytes, channels, (int) sampleRate);
459
TRACE3("enc=%d, signed=%d, bigEndian=%d\n", encoding, isSigned, bigEndian);
460
(*creator->env)->CallStaticVoidMethod(creator->env, creator->directAudioDeviceClass,
461
creator->addFormat, creator->vector, significantBits, frameSizeInBytes,
462
channels, sampleRate, encoding, isSigned, bigEndian);
463
}
464
465
////////////////////////////////////// JNI /////////////////////////////////////////////////////////////////////
466
467
/*
468
* Class: com_sun_media_sound_DirectAudioDevice
469
* Method: nGetFormats
470
* Signature: (IIZLjava/util/Vector;)V
471
*/
472
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nGetFormats
473
(JNIEnv *env, jclass clazz, jint mixerIndex, jint deviceID, jboolean isSource, jobject formats) {
474
475
#if USE_DAUDIO == TRUE
476
AddFormatCreator creator;
477
creator.env = env;
478
creator.vector = formats;
479
creator.directAudioDeviceClass = clazz;
480
creator.addFormat = (*env)->GetStaticMethodID(env, clazz, "addFormat",
481
"(Ljava/util/Vector;IIIFIZZ)V");
482
if (creator.addFormat == NULL) {
483
ERROR0("Could not get method ID for addFormat!\n");
484
} else {
485
DAUDIO_GetFormats((INT32) mixerIndex, (INT32) deviceID, (int) isSource, &creator);
486
}
487
#endif
488
}
489
490
491
492
/*
493
* Class: com_sun_media_sound_DirectAudioDevice
494
* Method: nOpen
495
* Signature: (IIZIFIIZZI)J
496
*/
497
JNIEXPORT jlong JNICALL Java_com_sun_media_sound_DirectAudioDevice_nOpen
498
(JNIEnv* env, jclass clazz, jint mixerIndex, jint deviceID, jboolean isSource,
499
jint encoding, jfloat sampleRate, jint sampleSizeInBits, jint frameSize, jint channels,
500
jboolean isSigned, jboolean isBigendian, jint bufferSizeInBytes) {
501
502
DAUDIO_Info* info = NULL;
503
#if USE_DAUDIO == TRUE
504
505
info = (DAUDIO_Info*) malloc(sizeof(DAUDIO_Info));
506
if (info == NULL) {
507
ERROR0("DirectAudioDevice_nOpen: Out of memory!\n");
508
} else {
509
info->handle =DAUDIO_Open((int) mixerIndex, (INT32) deviceID, (int) isSource,
510
(int) encoding, (float) sampleRate, (int) sampleSizeInBits,
511
(int) frameSize, (int) channels,
512
(int) isSigned, (int) isBigendian, (int) bufferSizeInBytes);
513
if (!info->handle) {
514
free(info);
515
info = NULL;
516
} else {
517
info->encoding = encoding;
518
info->sampleSizeInBits = sampleSizeInBits;
519
info->frameSize = frameSize;
520
info->channels = channels;
521
info->isSigned = isSigned;
522
info->isBigEndian = isBigendian && (sampleSizeInBits > 8);
523
/* will be populated on demand */
524
info->conversionBuffer = NULL;
525
info->conversionBufferSize = 0;
526
}
527
}
528
#endif
529
return (jlong) (UINT_PTR) info;
530
}
531
532
/*
533
* Class: com_sun_media_sound_DirectAudioDevice
534
* Method: nStart
535
* Signature: (JZ)V
536
*/
537
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nStart
538
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
539
#if USE_DAUDIO == TRUE
540
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
541
if (info && info->handle) {
542
DAUDIO_Start(info->handle, (int) isSource);
543
}
544
#endif
545
}
546
547
548
/*
549
* Class: com_sun_media_sound_DirectAudioDevice
550
* Method: nStop
551
* Signature: (JZ)V
552
*/
553
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nStop
554
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
555
#if USE_DAUDIO == TRUE
556
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
557
if (info && info->handle) {
558
DAUDIO_Stop(info->handle, (int) isSource);
559
}
560
#endif
561
}
562
563
564
/*
565
* Class: com_sun_media_sound_DirectAudioDevice
566
* Method: nClose
567
* Signature: (JZ)V
568
*/
569
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nClose
570
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
571
#if USE_DAUDIO == TRUE
572
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
573
if (info && info->handle) {
574
DAUDIO_Close(info->handle, (int) isSource);
575
if (info->conversionBuffer) {
576
free(info->conversionBuffer);
577
}
578
free(info);
579
}
580
#endif
581
}
582
583
/*
584
* Class: com_sun_media_sound_DirectAudioDevice
585
* Method: nWrite
586
* Signature: (J[BII)I
587
*/
588
JNIEXPORT jint JNICALL Java_com_sun_media_sound_DirectAudioDevice_nWrite
589
(JNIEnv *env, jclass clazz, jlong id, jbyteArray jData,
590
jint offset, jint len, jint conversionSize, jfloat leftGain, jfloat rightGain) {
591
int ret = -1;
592
#if USE_DAUDIO == TRUE
593
UINT8* data;
594
UINT8* dataOffset;
595
UINT8* convertedData;
596
jboolean didCopy;
597
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
598
599
/* a little sanity */
600
if (offset < 0 || len < 0) {
601
ERROR2("nWrite: wrong parameters: offset=%d, len=%d\n", offset, len);
602
return ret;
603
}
604
if (len == 0) return 0;
605
if (info && info->handle) {
606
data = (UINT8*) ((*env)->GetByteArrayElements(env, jData, &didCopy));
607
CHECK_NULL_RETURN(data, ret);
608
dataOffset = data;
609
dataOffset += (int) offset;
610
convertedData = dataOffset;
611
612
if (conversionSize > 0 || leftGain != 1.0f || rightGain != 1.0f) {
613
/* make sure we have a buffer for the intermediate data */
614
if (didCopy == JNI_FALSE) {
615
/* let's do our own copy */
616
if (info->conversionBuffer
617
&& info->conversionBufferSize < len) {
618
free(info->conversionBuffer);
619
info->conversionBuffer = NULL;
620
info->conversionBufferSize = 0;
621
}
622
if (!info->conversionBuffer) {
623
info->conversionBuffer = (UINT8*) malloc(len);
624
if (!info->conversionBuffer) {
625
// do not commit the native array
626
(*env)->ReleaseByteArrayElements(env, jData, (jbyte*) data, JNI_ABORT);
627
return -1;
628
}
629
info->conversionBufferSize = len;
630
}
631
convertedData = info->conversionBuffer;
632
}
633
if (((ABS_VALUE(leftGain - 1.0f) < 0.01)
634
&& (ABS_VALUE(rightGain - 1.0f) < 0.01))
635
|| info->encoding!=DAUDIO_PCM
636
|| ((info->channels * info->sampleSizeInBits / 8) != info->frameSize)
637
|| (info->sampleSizeInBits != 8 && info->sampleSizeInBits != 16)) {
638
handleSignEndianConversion((INT8*) dataOffset, (INT8*) convertedData, (int) len,
639
(int) conversionSize);
640
} else {
641
handleGainAndConversion(info, dataOffset, convertedData,
642
(int) len, (float) leftGain, (float) rightGain,
643
(int) conversionSize);
644
}
645
}
646
647
ret = DAUDIO_Write(info->handle, (INT8*) convertedData, (int) len);
648
649
// do not commit the native array
650
(*env)->ReleaseByteArrayElements(env, jData, (jbyte*) data, JNI_ABORT);
651
}
652
#endif
653
return (jint) ret;
654
}
655
656
/*
657
* Class: com_sun_media_sound_DirectAudioDevice
658
* Method: nRead
659
* Signature: (J[BII)I
660
*/
661
JNIEXPORT jint JNICALL Java_com_sun_media_sound_DirectAudioDevice_nRead
662
(JNIEnv* env, jclass clazz, jlong id, jbyteArray jData, jint offset, jint len, jint conversionSize) {
663
int ret = -1;
664
#if USE_DAUDIO == TRUE
665
char* data;
666
char* dataOffset;
667
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
668
669
/* a little sanity */
670
if (offset < 0 || len < 0) {
671
ERROR2("nRead: wrong parameters: offset=%d, len=%d\n", offset, len);
672
return ret;
673
}
674
if (info && info->handle) {
675
data = (char*) ((*env)->GetByteArrayElements(env, jData, NULL));
676
CHECK_NULL_RETURN(data, ret);
677
dataOffset = data;
678
dataOffset += (int) offset;
679
ret = DAUDIO_Read(info->handle, dataOffset, (int) len);
680
if (conversionSize > 0) {
681
handleSignEndianConversion(dataOffset, dataOffset, (int) len, (int) conversionSize);
682
}
683
// commit the native array
684
(*env)->ReleaseByteArrayElements(env, jData, (jbyte*) data, 0);
685
}
686
#endif
687
return (jint) ret;
688
}
689
690
/*
691
* Class: com_sun_media_sound_DirectAudioDevice
692
* Method: nGetBufferSize
693
* Signature: (JZ)I
694
*/
695
JNIEXPORT jint JNICALL Java_com_sun_media_sound_DirectAudioDevice_nGetBufferSize
696
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
697
int ret = -1;
698
#if USE_DAUDIO == TRUE
699
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
700
if (info && info->handle) {
701
ret = DAUDIO_GetBufferSize(info->handle, (int) isSource);
702
}
703
#endif
704
return (jint) ret;
705
}
706
707
708
/*
709
* Class: com_sun_media_sound_DirectAudioDevice
710
* Method: nIsStillDraining
711
* Signature: (JZ)Z
712
*/
713
JNIEXPORT jboolean JNICALL Java_com_sun_media_sound_DirectAudioDevice_nIsStillDraining
714
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
715
int ret = FALSE;
716
#if USE_DAUDIO == TRUE
717
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
718
if (info && info->handle) {
719
ret = DAUDIO_StillDraining(info->handle, (int) isSource)?TRUE:FALSE;
720
}
721
#endif
722
return (jboolean) ret;
723
}
724
725
726
/*
727
* Class: com_sun_media_sound_DirectAudioDevice
728
* Method: nFlush
729
* Signature: (JZ)V
730
*/
731
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nFlush
732
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
733
#if USE_DAUDIO == TRUE
734
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
735
if (info && info->handle) {
736
DAUDIO_Flush(info->handle, (int) isSource);
737
}
738
#endif
739
}
740
741
742
/*
743
* Class: com_sun_media_sound_DirectAudioDevice
744
* Method: nAvailable
745
* Signature: (JZ)I
746
*/
747
JNIEXPORT jint JNICALL Java_com_sun_media_sound_DirectAudioDevice_nAvailable
748
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
749
int ret = -1;
750
#if USE_DAUDIO == TRUE
751
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
752
if (info && info->handle) {
753
ret = DAUDIO_GetAvailable(info->handle, (int) isSource);
754
}
755
#endif
756
return (jint) ret;
757
}
758
759
760
/*
761
* Class: com_sun_media_sound_DirectAudioDevice
762
* Method: nGetBytePosition
763
* Signature: (JZJ)J
764
*/
765
JNIEXPORT jlong JNICALL Java_com_sun_media_sound_DirectAudioDevice_nGetBytePosition
766
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource, jlong javaBytePos) {
767
INT64 ret = (INT64) javaBytePos;
768
#if USE_DAUDIO == TRUE
769
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
770
if (info && info->handle) {
771
ret = DAUDIO_GetBytePosition(info->handle, (int) isSource, (INT64) javaBytePos);
772
}
773
#endif
774
return (jlong) ret;
775
}
776
777
/*
778
* Class: com_sun_media_sound_DirectAudioDevice
779
* Method: nSetBytePosition
780
* Signature: (JZJ)V
781
*/
782
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nSetBytePosition
783
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource, jlong pos) {
784
#if USE_DAUDIO == TRUE
785
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
786
if (info && info->handle) {
787
DAUDIO_SetBytePosition(info->handle, (int) isSource, (INT64) pos);
788
}
789
#endif
790
}
791
792
/*
793
* Class: com_sun_media_sound_DirectAudioDevice
794
* Method: nRequiresServicing
795
* Signature: (JZ)B
796
*/
797
JNIEXPORT jboolean JNICALL Java_com_sun_media_sound_DirectAudioDevice_nRequiresServicing
798
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
799
int ret = FALSE;
800
#if USE_DAUDIO == TRUE
801
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
802
if (info && info->handle) {
803
ret = DAUDIO_RequiresServicing(info->handle, (int) isSource);
804
}
805
#endif
806
return (jboolean) ret;
807
}
808
/*
809
* Class: com_sun_media_sound_DirectAudioDevice
810
* Method: nService
811
* Signature: (JZ)V
812
*/
813
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nService
814
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
815
#if USE_DAUDIO == TRUE
816
DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
817
if (info && info->handle) {
818
DAUDIO_Service(info->handle, (int) isSource);
819
}
820
#endif
821
}
822
823