alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (DirectAudioDevice.c)

This example Java source code file (DirectAudioDevice.c) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

convert_sample, daudio_info, format2code16, int8, jnicall, jnienv, jniexport, map_sample, output, to_sample, true, uint8, uint_ptr, use_daudio

The DirectAudioDevice.c Java example source code

/*
 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/* TODO:
 * - move all the conversion code into an own file
 */

//#define USE_TRACE
//#define USE_ERROR


#include <jni.h>
// for malloc
#ifdef _ALLBSD_SOURCE
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include "SoundDefs.h"
#include "DirectAudio.h"
#include "Utilities.h"
#include "com_sun_media_sound_DirectAudioDevice.h"


typedef struct {
    void* handle;
    int encoding;
    int sampleSizeInBits;
    int frameSize;
    int channels;
    int isSigned;
    int isBigEndian;
    UINT8* conversionBuffer;
    int conversionBufferSize;
} DAUDIO_Info;


//////////////////////////////////////////// MAP Conversion stuff /////////////////////////////////

/* 16 bit signed sample, native endianness, stored in 32-bits */
typedef INT32 MAP_Sample;

static INLINE UINT16 MAP_SWAP16_impl(UINT16 a) {
    return (a>>8) | (a<<8);
}

static INLINE UINT32 MAP_SWAP32_impl(UINT32 a) {
    return (a>>24)
        | ((a>>8) & 0xFF00)
        | ((a<<8) & 0xFF0000)
        | (a<<24);
}

static INLINE UINT32 MAP_SWAP16BIT(UINT32 sh) {
    return (UINT32) ((sh & 0xFF) << 8) | ((sh & 0xFF00) >> 8);
}

static INLINE INT32 MAP_ClipAndConvertToShort(MAP_Sample sample) {
    if (sample < -32768) {
        return -32768;
    }
    else if (sample > 32767) {
        return 32767;
    }
    return (INT32) sample;
}


static INLINE INT32 MAP_ClipAndConvertToShort_Swapped(MAP_Sample sample) {
    if (sample < -32768) {
        return 0x0080;
    }
    else if (sample > 32767) {
        return 0xFF7F;
    }
    return (INT32) (INT16) MAP_SWAP16BIT(sample);
}

static INLINE INT8 MAP_ClipAndConvertToByte(MAP_Sample sample) {
    if (sample < -32768) {
        return -128;
    }
    else if (sample > 32767) {
        return 127;
    }
    return (INT8) (sample >> 8);
}


static INLINE UINT8 MAP_ClipAndConvertToUByte(MAP_Sample sample) {
    if (sample < -32768) {
        return 0;
    }
    else if (sample > 32767) {
        return 255;
    }
    return (UINT8) ((sample >> 8) + 128);
}

/* conversion from/to 16 bit signed little endian to native endian samples */
#ifdef _LITTLE_ENDIAN
#define MAP_LE_SHORT2SAMPLE(sh) ((MAP_Sample) (sh))
#define MAP_SAMPLE2LE_SHORT(sample) (sample)
#define MAP_SAMPLE2LE_SHORT_CLIP(sample) MAP_ClipAndConvertToShort(sample)
#else
#define MAP_LE_SHORT2SAMPLE(sh) ((MAP_Sample) (INT16) MAP_SWAP16BIT(sh))
#define MAP_SAMPLE2LE_SHORT(sample) (INT16) MAP_SWAP16BIT(sample)
#define MAP_SAMPLE2LE_SHORT_CLIP(sample) MAP_ClipAndConvertToShort_Swapped(sample)
#endif

/* conversion from/to 16 bit signed big endian to native endian samples */
#ifndef _LITTLE_ENDIAN
#define MAP_BE_SHORT2SAMPLE(sh) ((MAP_Sample) (sh))
#define MAP_SAMPLE2BE_SHORT(sample) (sample)
#define MAP_SAMPLE2BE_SHORT_CLIP(sample) MAP_ClipAndConvertToShort(sample)
#else
#define MAP_BE_SHORT2SAMPLE(sh) ((MAP_Sample) (INT16) MAP_SWAP16BIT(sh))
#define MAP_SAMPLE2BE_SHORT(sample) ((INT16) MAP_SWAP16BIT(sample))
#define MAP_SAMPLE2BE_SHORT_CLIP(sample) MAP_ClipAndConvertToShort_Swapped(sample)
#endif

/* conversion from/to 8 bit samples */
#define MAP_INT82SAMPLE(by) ((MAP_Sample) (((INT32) ((INT8) (by))) << 8))
#define MAP_UINT82SAMPLE(by) ((MAP_Sample) (((INT32) ((UINT8) (by) - 128)) << 8))
#define MAP_SAMPLE2UINT8(sample) ((UINT8) ((((MAP_Sample) (sample)) >> 8) + 128))
#define MAP_SAMPLE2INT8(sample) ((INT8) (((MAP_Sample) (sample)) >> 8))
#define MAP_SAMPLE2UINT8_CLIP(sample) MAP_ClipAndConvertToUByte(sample)
#define MAP_SAMPLE2INT8_CLIP(sample) MAP_ClipAndConvertToByte(sample)

/* macros for endian conversion */
#ifdef _LITTLE_ENDIAN
#define MAP_NATIVE2LE16(a) (a)
#define MAP_NATIVE2BE16(a) MAP_SWAP16_impl(a)
#define MAP_NATIVE2LE32(a) (a)
#define MAP_NATIVE2BE32(a) MAP_SWAP32_impl(a)
#else
#define MAP_NATIVE2LE16(a) MAP_SWAP16_impl(a)
#define MAP_NATIVE2BE16(a) (a)
#define MAP_NATIVE2LE32(a) MAP_SWAP32_impl(a)
#define MAP_NATIVE2BE32(a) (a)
#endif
#define MAP_LE2NATIVE16(a) MAP_NATIVE2LE16(a)
#define MAP_BE2NATIVE16(a) MAP_NATIVE2BE16(a)
#define MAP_LE2NATIVE32(a) MAP_NATIVE2LE32(a)
#define MAP_BE2NATIVE32(a) MAP_NATIVE2BE32(a)


////////////////////////////// Utility function /////////////////////////////////

/*
 * conversion of this buffer:
 * conversion size=1 -> each byte is converted from signed to unsigned or vice versa
 * conversion size=2,3,4: the order of bytes in a sample is reversed (endianness)
 * for sign conversion of a 24-bit sample stored in 32bits, 4 should be passed
 * as conversionSize
 */
void handleSignEndianConversion(INT8* data, INT8* output, int byteSize, int conversionSize) {
    TRACE1("conversion with size %d\n", conversionSize);
    switch (conversionSize) {
    case 1: {
        while (byteSize > 0) {
            *output = *data + (char) 128; // use wrap-around
            byteSize--;
            data++;
            output++;
        }
        break;
    }
    case 2: {
        INT8 h;
        byteSize = byteSize / 2;
        while (byteSize > 0) {
            h = *data;
            data++;
            *output = *data;
            output++;
            *output = h;
            byteSize--;
            data++; output++;
        }
        break;
    }
    case 3: {
        INT8 h;
        byteSize = byteSize / 3;
        while (byteSize > 0) {
            h = *data;
            *output = data[2];
            data++; output++;
            *output = *data;
            data++; output++;
            *output = h;
            data++; output++;
            byteSize--;
        }
        break;
    }
    case 4: {
        INT8 h1, h2;
        byteSize = byteSize / 4;
        while (byteSize > 0) {
            h1 = data[0];
            h2 = data[1];
            *output = data[3]; output++;
            *output = data[2]; output++;
            *output = h2; output++;
            *output = h1; output++;
            data += 4;
            byteSize--;
        }
        break;
    }
    default:
        ERROR1("DirectAudioDevice.c: wrong conversionSize %d!\n", conversionSize);
    }
}

/* aply the gain to one sample */
#define CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE, FROM_SAMPLE, FACTOR) \
    /* convert to MAP_Sample native type */     \
    sample = TO_SAMPLE(*INPUT);                 \
    /* apply gain */                            \
    sample = (MAP_Sample) (sample * FACTOR);    \
    /* convert to output type */                \
    (*OUTPUT) = FROM_SAMPLE(sample);            \
    INPUT++; OUTPUT++


/* macro for conversion of a mono block */
#define LOOP_M(INPUT, OUTPUT, TO_SAMPLE, FROM_SAMPLE, FROM_SAMPLE_CLIP) \
    if (leftGain > 1.0) {                                               \
        for ( ; len > 0; --len) {                                       \
            CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                    \
                           FROM_SAMPLE_CLIP, leftGain);                 \
        }                                                               \
    } else {                                                            \
        for ( ; len > 0; --len) {                                       \
            CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                    \
                           FROM_SAMPLE, leftGain);                      \
        }                                                               \
    }                                                                   \
    break

/* macro for conversion of a stereo block */
#define LOOP_S(INPUT, OUTPUT, TO_SAMPLE, FROM_SAMPLE, FROM_SAMPLE_CLIP) \
    if (leftGain > 1.0) {                                               \
        if (rightGain > 1.0) {                                          \
            for ( ; len > 0; --len) {                                   \
                CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                \
                               FROM_SAMPLE_CLIP, leftGain);             \
                CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                \
                               FROM_SAMPLE_CLIP, rightGain);            \
            }                                                           \
        } else {                                                        \
            for ( ; len > 0; --len) {                                   \
                CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                \
                               FROM_SAMPLE_CLIP, leftGain);             \
                CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                \
                               FROM_SAMPLE, rightGain);                 \
            }                                                           \
        }                                                               \
    } else {                                                            \
        if (rightGain > 1.0) {                                          \
            for ( ; len > 0; --len) {                                   \
                CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                \
                               FROM_SAMPLE, leftGain);                  \
                CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                \
                               FROM_SAMPLE_CLIP, rightGain);            \
            }                                                           \
        } else {                                                        \
            for ( ; len > 0; --len) {                                   \
                CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                \
                               FROM_SAMPLE, leftGain);                  \
                CONVERT_SAMPLE(INPUT, OUTPUT, TO_SAMPLE,                \
                               FROM_SAMPLE, rightGain);                 \
            }                                                           \
        }                                                               \
    }                                                                   \
    break

#define FORMAT2CODE(channels, bits, inSigned, outSigned, inBigEndian, outBigEndian) \
      (channels << 20)                                                  \
    | (bits << 4)                                                       \
    | ((inSigned & 1) << 3)                                             \
    | ((outSigned & 1) << 2)                                            \
    | ((inBigEndian & 1) << 1)                                          \
    | (outBigEndian & 1)

#define FORMAT2CODE8(channels, inSigned, outSigned)           \
    FORMAT2CODE(channels, 8, inSigned, outSigned, 0, 0)

#define FORMAT2CODE16(channels, inBigEndian, outBigEndian)    \
    FORMAT2CODE(channels, 16, 1, 1, inBigEndian, outBigEndian)


void handleGainAndConversion(DAUDIO_Info* info, UINT8* input, UINT8* output,
                             int len, float leftGain, float rightGain,
                             int conversionSize) {
    INT8* input8 = (INT8*) input;
    INT8* output8 = (INT8*) output;
    INT16* input16 = (INT16*) input;
    INT16* output16 = (INT16*) output;
    MAP_Sample sample;

    int inIsSigned = info->isSigned;
    int inIsBigEndian = info->isBigEndian;
    if (conversionSize == 1) {
        /* 8-bit conversion: change sign */
        inIsSigned = !inIsSigned;
    }
    else if (conversionSize > 1) {
        /* > 8-bit conversion: change endianness */
        inIsBigEndian = !inIsBigEndian;
    }
    if (info->frameSize <= 0) {
        ERROR1("DirectAudiODevice: invalid framesize=%d\n", info->frameSize);
        return;
    }
    len /= info->frameSize;
    TRACE3("handleGainAndConversion: len=%d frames, leftGain=%f, rightGain=%f, ",
           len, leftGain, rightGain);
    TRACE3("channels=%d, sampleSizeInBits=%d, frameSize=%d, ",
           (int) info->channels, (int) info->sampleSizeInBits, (int) info->frameSize);
    TRACE4("signed:%d -> %d, endian: %d -> %d",
           (int) inIsSigned, (int) info->isSigned,
           (int) inIsBigEndian, (int) info->isBigEndian);
    TRACE1("convSize=%d\n", conversionSize);

    switch (FORMAT2CODE(info->channels,
                        info->sampleSizeInBits,
                        inIsSigned,
                        info->isSigned,
                        inIsBigEndian,
                        info->isBigEndian)) {
        /* 8-bit mono */
    case FORMAT2CODE8(1, 0, 0):
        LOOP_M(input8, output8, MAP_UINT82SAMPLE,
               MAP_SAMPLE2UINT8, MAP_SAMPLE2UINT8_CLIP);
    case FORMAT2CODE8(1, 0, 1):
        LOOP_M(input8, output8, MAP_UINT82SAMPLE,
               MAP_SAMPLE2INT8, MAP_SAMPLE2INT8_CLIP);
    case FORMAT2CODE8(1, 1, 0):
        LOOP_M(input8, output8, MAP_INT82SAMPLE,
               MAP_SAMPLE2UINT8, MAP_SAMPLE2UINT8_CLIP);
    case FORMAT2CODE8(1, 1, 1):
        LOOP_M(input8, output8, MAP_INT82SAMPLE,
               MAP_SAMPLE2INT8, MAP_SAMPLE2INT8_CLIP);

    /* 8-bit stereo */
    case FORMAT2CODE8(2, 0, 0):
        LOOP_S(input8, output8, MAP_UINT82SAMPLE,
               MAP_SAMPLE2UINT8, MAP_SAMPLE2UINT8_CLIP);
    case FORMAT2CODE8(2, 0, 1):
        LOOP_S(input8, output8, MAP_UINT82SAMPLE,
               MAP_SAMPLE2INT8, MAP_SAMPLE2INT8_CLIP);
    case FORMAT2CODE8(2, 1, 0):
        LOOP_S(input8, output8, MAP_INT82SAMPLE,
               MAP_SAMPLE2UINT8, MAP_SAMPLE2UINT8_CLIP);
    case FORMAT2CODE8(2, 1, 1):
        LOOP_S(input8, output8, MAP_INT82SAMPLE,
               MAP_SAMPLE2INT8, MAP_SAMPLE2INT8_CLIP);

    /* 16-bit mono (only signed is accepted) */
    case FORMAT2CODE16(1, 0, 0):
        LOOP_M(input16, output16, MAP_LE_SHORT2SAMPLE,
               MAP_SAMPLE2LE_SHORT, MAP_SAMPLE2LE_SHORT_CLIP);
    case FORMAT2CODE16(1, 0, 1):
        LOOP_M(input16, output16, MAP_LE_SHORT2SAMPLE,
               MAP_SAMPLE2BE_SHORT, MAP_SAMPLE2BE_SHORT_CLIP);
    case FORMAT2CODE16(1, 1, 0):
        LOOP_M(input16, output16, MAP_BE_SHORT2SAMPLE,
               MAP_SAMPLE2LE_SHORT, MAP_SAMPLE2LE_SHORT_CLIP);
    case FORMAT2CODE16(1, 1, 1):
        LOOP_M(input16, output16, MAP_BE_SHORT2SAMPLE,
               MAP_SAMPLE2BE_SHORT, MAP_SAMPLE2BE_SHORT_CLIP);

    /* 16-bit stereo (only signed is accepted) */
    case FORMAT2CODE16(2, 0, 0):
        LOOP_S(input16, output16, MAP_LE_SHORT2SAMPLE,
               MAP_SAMPLE2LE_SHORT, MAP_SAMPLE2LE_SHORT_CLIP);
    case FORMAT2CODE16(2, 0, 1):
        LOOP_S(input16, output16, MAP_LE_SHORT2SAMPLE,
               MAP_SAMPLE2BE_SHORT, MAP_SAMPLE2BE_SHORT_CLIP);
    case FORMAT2CODE16(2, 1, 0):
        LOOP_S(input16, output16, MAP_BE_SHORT2SAMPLE,
               MAP_SAMPLE2LE_SHORT, MAP_SAMPLE2LE_SHORT_CLIP);
    case FORMAT2CODE16(2, 1, 1):
        LOOP_S(input16, output16, MAP_BE_SHORT2SAMPLE,
               MAP_SAMPLE2BE_SHORT, MAP_SAMPLE2BE_SHORT_CLIP);

    default:
        ERROR3("DirectAudioDevice: Cannot convert from native format: "
               "bits=%d, inSigned=%d  outSigned=%d, ",
               (int) info->sampleSizeInBits,
               (int) inIsSigned, (int) info->isSigned);
        ERROR2("inBigEndian=%d, outBigEndian=%d\n",
               (int) inIsBigEndian, (int) info->isBigEndian);
    }
}

float ABS_VALUE(float a) {
    return (a < 0)?-a:a;
}


//////////////////////////////////////////// DirectAudioDevice ////////////////////////////////////////////

/* ************************************** native control creation support ********************* */

// contains all the needed references so that the platform dependent code can call JNI wrapper functions
typedef struct tag_AddFormatCreator {
    // general JNI variables
    JNIEnv *env;
    // the vector to be filled with the formats
    jobject vector;
    // the class containing the addFormat method
    jclass directAudioDeviceClass;
    // the method to be called to add the format
    jmethodID addFormat; // signature (Ljava/util/Vector;IIFIBB)V
} AddFormatCreator;

void DAUDIO_AddAudioFormat(void* creatorV, int significantBits, int frameSizeInBytes,
                           int channels, float sampleRate,
                           int encoding, int isSigned,
                           int bigEndian) {
    AddFormatCreator* creator = (AddFormatCreator*) creatorV;
    if (frameSizeInBytes <= 0) {
        if (channels > 0) {
            frameSizeInBytes = ((significantBits + 7) / 8) * channels;
        } else {
            frameSizeInBytes = -1;
        }
    }
    TRACE4("AddAudioFormat with sigBits=%d bits, frameSize=%d bytes, channels=%d, sampleRate=%d ",
           significantBits, frameSizeInBytes, channels, (int) sampleRate);
    TRACE3("enc=%d, signed=%d, bigEndian=%d\n", encoding, isSigned, bigEndian);
    (*creator->env)->CallStaticVoidMethod(creator->env, creator->directAudioDeviceClass,
                                          creator->addFormat, creator->vector, significantBits, frameSizeInBytes,
                                          channels, sampleRate, encoding, isSigned, bigEndian);
}

////////////////////////////////////// JNI /////////////////////////////////////////////////////////////////////

/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nGetFormats
 * Signature: (IIZLjava/util/Vector;)V
 */
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nGetFormats
(JNIEnv *env, jclass clazz, jint mixerIndex, jint deviceID, jboolean isSource, jobject formats) {

#if USE_DAUDIO == TRUE
    AddFormatCreator creator;
    creator.env = env;
    creator.vector = formats;
    creator.directAudioDeviceClass = clazz;
    creator.addFormat = (*env)->GetStaticMethodID(env, clazz, "addFormat",
                                                  "(Ljava/util/Vector;IIIFIZZ)V");
    if (creator.addFormat == NULL) {
        ERROR0("Could not get method ID for addFormat!\n");
    } else {
        DAUDIO_GetFormats((INT32) mixerIndex, (INT32) deviceID, (int) isSource, &creator);
    }
#endif
}



/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nOpen
 * Signature: (IIZIFIIZZI)J
 */
JNIEXPORT jlong JNICALL Java_com_sun_media_sound_DirectAudioDevice_nOpen
(JNIEnv* env, jclass clazz, jint mixerIndex, jint deviceID, jboolean isSource,
 jint encoding, jfloat sampleRate, jint sampleSizeInBits, jint frameSize, jint channels,
 jboolean isSigned, jboolean isBigendian, jint bufferSizeInBytes) {

    DAUDIO_Info* info = NULL;
#if USE_DAUDIO == TRUE

    info = (DAUDIO_Info*) malloc(sizeof(DAUDIO_Info));
    if (info == NULL) {
        ERROR0("DirectAudioDevice_nOpen: Out of memory!\n");
    } else {
        info->handle =DAUDIO_Open((int) mixerIndex, (INT32) deviceID, (int) isSource,
                                  (int) encoding, (float) sampleRate, (int) sampleSizeInBits,
                                  (int) frameSize, (int) channels,
                                  (int) isSigned, (int) isBigendian, (int) bufferSizeInBytes);
        if (!info->handle) {
            free(info);
            info = NULL;
        } else {
            info->encoding = encoding;
            info->sampleSizeInBits = sampleSizeInBits;
            info->frameSize = frameSize;
            info->channels = channels;
            info->isSigned = isSigned;
            info->isBigEndian = isBigendian && (sampleSizeInBits > 8);
            /* will be populated on demand */
            info->conversionBuffer = NULL;
            info->conversionBufferSize = 0;
        }
    }
#endif
    return (jlong) (UINT_PTR) info;
}

/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nStart
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nStart
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        DAUDIO_Start(info->handle, (int) isSource);
    }
#endif
}


/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nStop
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nStop
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        DAUDIO_Stop(info->handle, (int) isSource);
    }
#endif
}


/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nClose
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nClose
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        DAUDIO_Close(info->handle, (int) isSource);
        if (info->conversionBuffer) {
            free(info->conversionBuffer);
        }
        free(info);
    }
#endif
}

/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nWrite
 * Signature: (J[BII)I
 */
JNIEXPORT jint JNICALL Java_com_sun_media_sound_DirectAudioDevice_nWrite
(JNIEnv *env, jclass clazz, jlong id, jbyteArray jData,
 jint offset, jint len, jint conversionSize, jfloat leftGain, jfloat rightGain) {
    int ret = -1;
#if USE_DAUDIO == TRUE
    UINT8* data;
    UINT8* dataOffset;
    UINT8* convertedData;
    jboolean didCopy;
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;

    /* a little sanity */
    if (offset < 0 || len < 0) {
        ERROR2("nWrite: wrong parameters: offset=%d, len=%d\n", offset, len);
        return ret;
    }
    if (len == 0) return 0;
    if (info && info->handle) {
        data = (UINT8*) ((*env)->GetByteArrayElements(env, jData, &didCopy));
        dataOffset = data;
        dataOffset += (int) offset;
        convertedData = dataOffset;

        if (conversionSize > 0 || leftGain != 1.0f || rightGain != 1.0f) {
            /* make sure we have a buffer for the intermediate data */
            if (didCopy == JNI_FALSE) {
                /* let's do our own copy */
                if (info->conversionBuffer
                    && info->conversionBufferSize < len) {
                    free(info->conversionBuffer);
                    info->conversionBuffer = NULL;
                    info->conversionBufferSize = 0;
                }
                if (!info->conversionBuffer) {
                    info->conversionBuffer = (UINT8*) malloc(len);
                    if (!info->conversionBuffer) {
                        // do not commit the native array
                        (*env)->ReleaseByteArrayElements(env, jData, (jbyte*) data, JNI_ABORT);
                        return -1;
                    }
                    info->conversionBufferSize = len;
                }
                convertedData = info->conversionBuffer;
            }
            if (((ABS_VALUE(leftGain - 1.0f) < 0.01)
                 && (ABS_VALUE(rightGain - 1.0f) < 0.01))
                || info->encoding!=DAUDIO_PCM
                || ((info->channels * info->sampleSizeInBits / 8) != info->frameSize)
                || (info->sampleSizeInBits != 8 && info->sampleSizeInBits != 16)) {
                handleSignEndianConversion((INT8*) dataOffset, (INT8*) convertedData, (int) len,
                                           (int) conversionSize);
            } else {
                handleGainAndConversion(info, dataOffset, convertedData,
                                        (int) len, (float) leftGain, (float) rightGain,
                                        (int) conversionSize);
            }
        }

        ret = DAUDIO_Write(info->handle, (INT8*) convertedData, (int) len);

        // do not commit the native array
        (*env)->ReleaseByteArrayElements(env, jData, (jbyte*) data, JNI_ABORT);
    }
#endif
    return (jint) ret;
}

/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nRead
 * Signature: (J[BII)I
 */
JNIEXPORT jint JNICALL Java_com_sun_media_sound_DirectAudioDevice_nRead
(JNIEnv* env, jclass clazz, jlong id, jbyteArray jData, jint offset, jint len, jint conversionSize) {
    int ret = -1;
#if USE_DAUDIO == TRUE
    char* data;
    char* dataOffset;
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;

    /* a little sanity */
    if (offset < 0 || len < 0) {
        ERROR2("nRead: wrong parameters: offset=%d, len=%d\n", offset, len);
        return ret;
    }
    if (info && info->handle) {
        data = (char*) ((*env)->GetByteArrayElements(env, jData, NULL));
        dataOffset = data;
        dataOffset += (int) offset;
        ret = DAUDIO_Read(info->handle, dataOffset, (int) len);
        if (conversionSize > 0) {
            handleSignEndianConversion(dataOffset, dataOffset, (int) len, (int) conversionSize);
        }
        // commit the native array
        (*env)->ReleaseByteArrayElements(env, jData, (jbyte*) data, 0);
    }
#endif
    return (jint) ret;
}

/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nGetBufferSize
 * Signature: (JZ)I
 */
JNIEXPORT jint JNICALL Java_com_sun_media_sound_DirectAudioDevice_nGetBufferSize
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
    int ret = -1;
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        ret = DAUDIO_GetBufferSize(info->handle, (int) isSource);
    }
#endif
    return (jint) ret;
}


/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nIsStillDraining
 * Signature: (JZ)Z
 */
JNIEXPORT jboolean JNICALL Java_com_sun_media_sound_DirectAudioDevice_nIsStillDraining
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
    int ret = FALSE;
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        ret = DAUDIO_StillDraining(info->handle, (int) isSource)?TRUE:FALSE;
    }
#endif
    return (jboolean) ret;
}


/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nFlush
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nFlush
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        DAUDIO_Flush(info->handle, (int) isSource);
    }
#endif
}


/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nAvailable
 * Signature: (JZ)I
 */
JNIEXPORT jint JNICALL Java_com_sun_media_sound_DirectAudioDevice_nAvailable
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
    int ret = -1;
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        ret = DAUDIO_GetAvailable(info->handle, (int) isSource);
    }
#endif
    return (jint) ret;
}


/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nGetBytePosition
 * Signature: (JZJ)J
 */
JNIEXPORT jlong JNICALL Java_com_sun_media_sound_DirectAudioDevice_nGetBytePosition
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource, jlong javaBytePos) {
    INT64 ret = (INT64) javaBytePos;
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        ret = DAUDIO_GetBytePosition(info->handle, (int) isSource, (INT64) javaBytePos);
    }
#endif
    return (jlong) ret;
}

/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nSetBytePosition
 * Signature: (JZJ)V
 */
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nSetBytePosition
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource, jlong pos) {
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        DAUDIO_SetBytePosition(info->handle, (int) isSource, (INT64) pos);
    }
#endif
}

/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nRequiresServicing
 * Signature: (JZ)B
 */
JNIEXPORT jboolean JNICALL Java_com_sun_media_sound_DirectAudioDevice_nRequiresServicing
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
    int ret = FALSE;
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        ret = DAUDIO_RequiresServicing(info->handle, (int) isSource);
    }
#endif
    return (jboolean) ret;
}
/*
 * Class:     com_sun_media_sound_DirectAudioDevice
 * Method:    nService
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL Java_com_sun_media_sound_DirectAudioDevice_nService
(JNIEnv* env, jclass clazz, jlong id, jboolean isSource) {
#if USE_DAUDIO == TRUE
    DAUDIO_Info* info = (DAUDIO_Info*) (UINT_PTR) id;
    if (info && info->handle) {
        DAUDIO_Service(info->handle, (int) isSource);
    }
#endif
}

Other Java examples (source code examples)

Here is a short list of links related to this Java DirectAudioDevice.c source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.