Converts the project to use a licensed WAVE file reader.

This is easier to distribute.
This commit is contained in:
Markil3
2021-07-24 14:12:42 -07:00
parent 97985044f8
commit adf4cea82c
19 changed files with 850 additions and 379 deletions

View File

@@ -4,14 +4,35 @@
#include <jni.h>
#include <stdio.h>
typedef struct {
short numChannels;
short bytesPerChannel;
int sampleRate;
} HeaderData;
static jclass InputStream;
static jclass AudioStream;
static jclass Header;
static jmethodID AudioStream_getHeader;
static jmethodID AudioStream_getByteStream;
static jmethodID AudioStream_readInt;
static jmethodID InputStream_readBuffer;
static jmethodID Header_getChunkId;
static jmethodID Header_getChunkSize;
static jmethodID Header_getFormat;
static jmethodID Header_getSubChunk1ID;
static jmethodID Header_getSubChunk1Size;
static jmethodID Header_getAudioFormat;
static jmethodID Header_getNumChannels;
static jmethodID Header_getSampleRate;
static jmethodID Header_getByteRate;
static jmethodID Header_getBlockAlign;
static jmethodID Header_getBitsPerSample;
static jmethodID Header_getSubChunk2ID;
static jmethodID Header_getSubChunk2Size;
static jobject currentFile = NULL;
static HeaderData currentHeader;
/**
* This function is used to initialize the static reference to java.io.InputStream class.
@@ -27,7 +48,7 @@ jclass getInputStreamClass(JNIEnv *env)
jclass tempClass = (*env)->FindClass(env, "java/io/InputStream");
if (tempClass == 0)
{
printf("Could not find class java/io/InputStream");
fprintf(stderr, "Could not find class java/io/InputStream");
return 0;
}
InputStream = (*env)->NewGlobalRef(env, tempClass);
@@ -49,7 +70,7 @@ jclass getAudioStreamClass(JNIEnv *env, jobject audio)
jclass tempClass = (*env)->GetObjectClass(env, audio);
if (tempClass == 0)
{
printf("Could not find class edu/regis/universeplayer_localPlayer/AudioFile");
fprintf(stderr, "Could not find class edu/regis/universeplayer_localPlayer/AudioFile");
return 0;
}
AudioStream = (*env)->NewGlobalRef(env, tempClass);
@@ -57,6 +78,21 @@ jclass getAudioStreamClass(JNIEnv *env, jobject audio)
return AudioStream;
}
jclass getHeaderClass(JNIEnv *env)
{
if (Header == 0)
{
jclass tempClass = (*env)->FindClass(env, "wave/WavHeader");
if (tempClass == 0)
{
fprintf(stderr, "Could not find wave/WavHeader");
return 0;
}
Header = (*env)->NewGlobalRef(env, tempClass);
}
return Header;
}
/**
* This function is used to initialize the static reference to AudioStream's getHeader method.
*
@@ -114,7 +150,7 @@ jmethodID getReadMethod(JNIEnv *env, jobject audio)
tempClass = getAudioStreamClass(env, audio);
if (tempClass == 0)
{
printf("Could not find AudioStream class");
fprintf(stderr, "Could not find AudioStream class");
}
else
{
@@ -127,7 +163,7 @@ jmethodID getReadMethod(JNIEnv *env, jobject audio)
tempClass = getInputStreamClass(env);
if (tempClass == 0)
{
printf("Could not find InputStream class");
fprintf(stderr, "Could not find InputStream class");
}
else
{
@@ -138,6 +174,124 @@ jmethodID getReadMethod(JNIEnv *env, jobject audio)
return AudioStream_readInt;
}
/**
* This function is used to initialize the static reference to WavHeader's various methods.
*
* @param env - A reference to the JVM.
*/
void getHeaderMethods(JNIEnv *env)
{
jclass tempClass = getHeaderClass(env);
if (tempClass == 0)
{
return;
}
if (Header_getChunkId == 0)
{
Header_getChunkId = (*env)->GetMethodID(env, tempClass, "getChunkID", "()[B");
if (Header_getChunkId == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getChunkID\n");
}
}
if (Header_getChunkSize == 0)
{
Header_getChunkSize = (*env)->GetMethodID(env, tempClass, "getChunkSize", "()I");
if (Header_getChunkSize == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getChunkSize\n");
}
}
if (Header_getFormat == 0)
{
Header_getFormat = (*env)->GetMethodID(env, tempClass, "getFormat", "()[B");
if (Header_getFormat == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getFormat\n");
}
}
if (Header_getSubChunk1ID == 0)
{
Header_getSubChunk1ID = (*env)->GetMethodID(env, tempClass, "getSubChunk1ID", "()[B");
if (Header_getSubChunk1ID == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getSubChunk1ID\n");
}
}
if (Header_getSubChunk1Size == 0)
{
Header_getSubChunk1Size = (*env)->GetMethodID(env, tempClass, "getSubChunk1Size", "()I");
if (Header_getSubChunk1Size == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getSubChunk1Size\n");
}
}
if (Header_getAudioFormat == 0)
{
Header_getAudioFormat = (*env)->GetMethodID(env, tempClass, "getAudioFormat", "()S");
if (Header_getAudioFormat == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getAudioFormat\n");
}
}
if (Header_getNumChannels == 0)
{
Header_getNumChannels = (*env)->GetMethodID(env, tempClass, "getNumChannels", "()S");
if (Header_getNumChannels == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getNumChannels\n");
}
}
if (Header_getSampleRate == 0)
{
Header_getSampleRate = (*env)->GetMethodID(env, tempClass, "getSampleRate", "()I");
if (Header_getSampleRate == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getSampleRate\n");
}
}
if (Header_getByteRate == 0)
{
Header_getByteRate = (*env)->GetMethodID(env, tempClass, "getByteRate", "()I");
if (Header_getByteRate == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getByteRate\n");
}
}
if (Header_getBlockAlign == 0)
{
Header_getBlockAlign = (*env)->GetMethodID(env, tempClass, "getBlockAlign", "()S");
if (Header_getBlockAlign == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getBlockAlign\n");
}
}
if (Header_getBitsPerSample == 0)
{
Header_getBitsPerSample = (*env)->GetMethodID(env, tempClass, "getBitsPerSample", "()S");
if (Header_getBitsPerSample == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getBitsPerSample\n");
}
}
if (Header_getSubChunk2ID == 0)
{
Header_getSubChunk2ID = (*env)->GetMethodID(env, tempClass, "getSubChunk2ID", "()[B");
if (Header_getSubChunk2ID == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getSubChunk2ID\n");
}
}
if (Header_getSubChunk2Size == 0)
{
Header_getSubChunk2Size = (*env)->GetMethodID(env, tempClass, "getSubChunk2Size", "()I");
if (Header_getSubChunk2Size == 0)
{
fprintf(stderr, "Could not find wave/WavHeader#getSubChunk2Size\n");
}
}
}
/**
* Obtains an audio stream's header.
* @param env - A reference to the JVM.
@@ -213,12 +367,12 @@ int readBuffer(JNIEnv *env, jobject stream, char* buffer, int bufferSize)
getReadMethod(env, stream);
if (InputStream_readBuffer == 0)
{
printf("readBuffer method not found\n");
fprintf(stderr, "readBuffer method not found\n");
return 0;
}
if (AudioStream_readInt == 0)
{
printf("readInt method not found\n");
fprintf(stderr, "readInt method not found\n");
return 0;
}
}
@@ -234,24 +388,49 @@ int readBuffer(JNIEnv *env, jobject stream, char* buffer, int bufferSize)
return returnValue;
}
/**
* Converts a WavHeader into something more easily accessible by native code.
*
* @param env - The JVM.
* @param header - The header to read.
* @param headerStruct - The header to write the data to.
*/
HeaderData readHeader(JNIEnv *env, jobject header, HeaderData *headerStruct)
{
if (Header == 0)
{
getHeaderMethods(env);
}
headerStruct->numChannels = (short) (*env)->CallShortMethod(env, header, Header_getNumChannels);
headerStruct->bytesPerChannel = (short) (*env)->CallShortMethod(env, header, Header_getBitsPerSample);
headerStruct->sampleRate = (int) (*env)->CallIntMethod(env, header, Header_getSampleRate);
}
/**
* Sets the file currently being used
*/
JNIEXPORT jint JNICALL Java_edu_regis_universeplayer_localPlayer_Player_setCurrentFile(JNIEnv *env, jobject obj, jobject stream, jshort numChannels, jshort bitsPerSample, jint sampleRate)
{
jobject header;
if (currentFile != NULL)
{
(*env)->DeleteLocalRef(env, currentFile);
}
currentFile = (*env)->NewGlobalRef(env, stream);
printf("Setting File\n");
return 0;
header = getHeader(env, stream);
readHeader(env, header, &currentHeader);
return updatePlayer(env, obj, stream, numChannels, bitsPerSample, sampleRate);
}
JNIEXPORT void JNICALL Java_edu_regis_universeplayer_localPlayer_Player_save(JNIEnv *env, jobject obj, jstring location)
{
int BUFFER_SIZE = 256;
char buffer[BUFFER_SIZE];
const int BUFFER_SIZE = 256;
/*
* Windows doesn't seem to like using even a constant for determining array
* size.
*/
char buffer[256];
int read;
FILE *output;
@@ -262,7 +441,7 @@ JNIEXPORT void JNICALL Java_edu_regis_universeplayer_localPlayer_Player_save(JNI
if (output == NULL)
{
printf("File %s can't be opened\n", locationPath);
fprintf(stderr, "File %s can't be opened\n", locationPath);
return;
}
@@ -270,7 +449,7 @@ JNIEXPORT void JNICALL Java_edu_regis_universeplayer_localPlayer_Player_save(JNI
jbyteArray headerData = getByteStream(env, currentFile);
jsize headerLength = (*env)->GetArrayLength(env, headerData);
jbyte* header = (*env)->GetByteArrayElements(env, headerData, 0);
char headerBuff[headerLength];
char headerBuff[256];
for (int i = 0; i < headerLength; i++)
{
headerBuff[i] = header[i];

View File

@@ -0,0 +1,11 @@
/*
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
#include <jni.h>
#include <stdio.h>
int updatePlayer(JNIEnv *env, jobject obj, jobject stream, jshort numChannels, jshort bitsPerSample, jint sampleRate)
{
printf("Updating File\n");
return 0;
}