Merge remote-tracking branch 'sound/develop' into sound

This commit is contained in:
2013-07-31 11:05:39 +02:00
56 changed files with 4019 additions and 0 deletions

154
cpp/pipe/.cproject Normal file
View File

@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.config.gnu.mingw.so.debug.1813551917">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.so.debug.1813551917" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<macros>
<stringMacro name="target" type="VALUE_TEXT" value="pipe"/>
<stringMacro name="jdk" type="VALUE_PATH_DIR" value="C:\Program Files (x86)\Java\jdk1.7.0"/>
</macros>
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Pipe"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Pipe/Debug"/>
<entry flags="RESOLVED" kind="libraryFile" name="Pipe" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="dll" artifactName="${target}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mingw.so.debug.1813551917" name="Debug" parent="cdt.managedbuild.config.gnu.mingw.so.debug" postbuildStep="./copy.bat">
<folderInfo id="cdt.managedbuild.config.gnu.mingw.so.debug.1813551917." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.so.debug.139919199" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.so.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.mingw.so.debug.1189720953" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.mingw.so.debug"/>
<builder buildPath="${workspace_loc:/Pipe/Debug}" id="cdt.managedbuild.tool.gnu.builder.mingw.base.482966139" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/>
<tool command="as" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.assembler.mingw.so.debug.268346771" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.so.debug">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.665305624" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1220825669" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.debug.1175271295" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.debug">
<option id="gnu.cpp.compiler.mingw.so.debug.option.optimization.level.1125922986" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.so.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.mingw.so.debug.option.debugging.level.1641613502" name="Debug Level" superClass="gnu.cpp.compiler.mingw.so.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.939510920" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug.1399500702" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug">
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.mingw.so.debug.option.optimization.level.234429006" name="Optimization Level" superClass="gnu.c.compiler.mingw.so.debug.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.mingw.so.debug.option.debugging.level.1525375982" name="Debug Level" superClass="gnu.c.compiler.mingw.so.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="gnu.c.compiler.option.include.paths.88885521" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${jdk}/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${jdk}/include/win32&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.747324638" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.so.debug.1007471610" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.so.debug">
<option defaultValue="true" id="gnu.c.link.mingw.so.debug.option.shared.1850054546" name="Shared (-shared)" superClass="gnu.c.link.mingw.so.debug.option.shared" valueType="boolean"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.debug.2022087314" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.debug">
<option defaultValue="true" id="gnu.cpp.link.mingw.so.debug.option.shared.357933903" name="Shared (-shared)" superClass="gnu.cpp.link.mingw.so.debug.option.shared" valueType="boolean"/>
<option id="gnu.cpp.link.option.flags.1387180659" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-Wl,--kill-at -static-libgcc" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2125675597" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<outputType id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.debug.output.216466795" outputPrefix="" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.debug.output"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="cdt.managedbuild.config.gnu.mingw.so.release.2043271336">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.so.release.2043271336" moduleId="org.eclipse.cdt.core.settings" name="Release">
<macros>
<stringMacro name="target" type="VALUE_TEXT" value="pipe"/>
<stringMacro name="jdk" type="VALUE_PATH_DIR" value="C:\Program Files (x86)\Java\jdk1.7.0"/>
</macros>
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Pipe"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Pipe/Release"/>
<entry flags="RESOLVED" kind="libraryFile" name="Pipe" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="dll" artifactName="${target}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mingw.so.release.2043271336" name="Release" parent="cdt.managedbuild.config.gnu.mingw.so.release" postbuildStep="./copy.bat">
<folderInfo id="cdt.managedbuild.config.gnu.mingw.so.release.2043271336." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.so.release.1271980283" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.so.release">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.mingw.so.release.368721242" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.mingw.so.release"/>
<builder buildPath="${workspace_loc:/Pipe/Release}" id="cdt.managedbuild.tool.gnu.builder.mingw.base.2065732021" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.so.release.109377381" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.so.release">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.689046683" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1183393349" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release.726851992" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release">
<option id="gnu.cpp.compiler.mingw.so.release.option.optimization.level.2002053108" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.so.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
<option id="gnu.cpp.compiler.mingw.so.release.option.debugging.level.907936589" name="Debug Level" superClass="gnu.cpp.compiler.mingw.so.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.204761037" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release.1321746613" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release">
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.mingw.so.release.option.optimization.level.735179609" name="Optimization Level" superClass="gnu.c.compiler.mingw.so.release.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.mingw.so.release.option.debugging.level.265400846" name="Debug Level" superClass="gnu.c.compiler.mingw.so.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="gnu.c.compiler.option.include.paths.1576117703" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${jdk}/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${jdk}/include/win32&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1173268559" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.so.release.1652830435" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.so.release">
<option defaultValue="true" id="gnu.c.link.mingw.so.release.option.shared.1257748519" name="Shared (-shared)" superClass="gnu.c.link.mingw.so.release.option.shared" valueType="boolean"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.release.1600111105" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.release">
<option defaultValue="true" id="gnu.cpp.link.mingw.so.release.option.shared.684498624" name="Shared (-shared)" superClass="gnu.cpp.link.mingw.so.release.option.shared" valueType="boolean"/>
<option id="gnu.cpp.link.option.flags.51892807" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-Wl,--kill-at -static-libgcc" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.656026656" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<outputType id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.release.output.432743873" outputPrefix="" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.release.output"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="Pipe.cdt.managedbuild.target.gnu.mingw.so.1070782613" name="Shared Library" projectType="cdt.managedbuild.target.gnu.mingw.so"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.1813551917;cdt.managedbuild.config.gnu.mingw.so.debug.1813551917.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.debug.1175271295;cdt.managedbuild.tool.gnu.cpp.compiler.input.939510920">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.release.2043271336;cdt.managedbuild.config.gnu.mingw.so.release.2043271336.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release.726851992;cdt.managedbuild.tool.gnu.cpp.compiler.input.204761037">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.release.2043271336;cdt.managedbuild.config.gnu.mingw.so.release.2043271336.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release.1321746613;cdt.managedbuild.tool.gnu.c.compiler.input.1173268559">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.1813551917;cdt.managedbuild.config.gnu.mingw.so.debug.1813551917.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug.1399500702;cdt.managedbuild.tool.gnu.c.compiler.input.747324638">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="refreshScope"/>
</cproject>

1
cpp/pipe/Debug/copy.bat Normal file
View File

@@ -0,0 +1 @@
copy pipe.dll ..\..\..\java\pipe.dll

BIN
cpp/pipe/Debug/pipe.dll Normal file

Binary file not shown.

View File

@@ -0,0 +1 @@
copy pipe.dll ..\..\..\java\pipe.dll

BIN
cpp/pipe/Release/pipe.dll Normal file

Binary file not shown.

262
cpp/pipe/src/pipe.c Normal file
View File

@@ -0,0 +1,262 @@
#include <windows.h>
#include <strsafe.h>
#include <jni.h>
#include "pipe.h"
#define DEBUG 0
JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateNamedPipe
(
JNIEnv *env,
jclass className,
jstring sPipeName,
jint dwOpenMode,
jint dwPipeMode,
jint nMaxInstances,
jint nOutBufferSize,
jint nInBufferSize,
jint nDefaultTimeOut,
jint lpSecurityAttributes
)
{
HANDLE pipeHandler;
LPCSTR pipeName;
pipeName = (*env)->GetStringUTFChars(env, sPipeName, NULL);
if (pipeName == NULL)
return -1;
if (DEBUG)
{
printf("Native: Pipe Name %s\n", pipeName);
printf("Native: dwOpenMode %d\n", dwOpenMode);
printf("Native: dwPipeMode %d\n", dwPipeMode);
printf("Native: nMaxInstances %d\n", nMaxInstances);
printf("Native: nOutBufferSize %d\n", nOutBufferSize);
printf("Native: nInBufferSize %d\n", nInBufferSize);
printf("Native: nDefaultTimeOut %d\n", nDefaultTimeOut);
}
pipeHandler = CreateNamedPipe((LPCSTR)pipeName, dwOpenMode, dwPipeMode, nMaxInstances, nOutBufferSize, nInBufferSize,
nDefaultTimeOut, (LPSECURITY_ATTRIBUTES) lpSecurityAttributes);
(*env)->ReleaseStringUTFChars(env, sPipeName, pipeName);
return (jint) pipeHandler;
}
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_ConnectNamedPipe
(
JNIEnv *env,
jclass className,
jint hNamedPipe,
jint lpOverlapped
)
{
BOOL fConnected;
HANDLE pipeHandler = (HANDLE) hNamedPipe;
fConnected = ConnectNamedPipe(pipeHandler, (LPOVERLAPPED) lpOverlapped);
return fConnected;
}
JNIEXPORT jint JNICALL Java_pipe_Pipe_GetLastError
(
JNIEnv *env,
jclass className
)
{
DWORD errorNumber = GetLastError();
return (jint) errorNumber;
}
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_CloseHandle
(
JNIEnv *env,
jclass className,
jint hNamedPipe
)
{
BOOL result;
HANDLE pipeHandler = (HANDLE) hNamedPipe;
result = CloseHandle(pipeHandler);
return result;
}
JNIEXPORT jbyteArray JNICALL Java_pipe_Pipe_ReadFile
(
JNIEnv *env,
jclass className,
jint hNamedPipe,
jint nNumberOfBytesToRead
)
{
int bytesRead = 0;
BOOL result;
HANDLE pipeHandler = (HANDLE) hNamedPipe;
LPVOID buffer;
jbyteArray lpBuffer;
buffer = (LPVOID)LocalAlloc(LMEM_ZEROINIT, nNumberOfBytesToRead);
if (DEBUG)
{
printf("Native: Before ReadFile pipeHandler %d nNumberOfBytesToRead %d\n", pipeHandler, nNumberOfBytesToRead);
}
result = ReadFile(pipeHandler, (LPVOID) buffer, (DWORD) nNumberOfBytesToRead, &bytesRead, (LPOVERLAPPED) 0);
if (result)
{
lpBuffer = (*env)->NewByteArray(env, (jsize) bytesRead);
(*env)->SetByteArrayRegion(env, lpBuffer, 0, (jsize) bytesRead, (jbyte *) buffer);
} else
bytesRead = 0;
LocalFree(buffer);
if (DEBUG)
{
printf("Native: After ReadFile BytesRead %d\n", bytesRead);
}
return lpBuffer;
}
JNIEXPORT jint JNICALL Java_pipe_Pipe_WriteFile
(
JNIEnv *env,
jclass className,
jint hNamedPipe,
jbyteArray lpBuffer,
jint nNumberOfBytesToWrite
)
{
int bytesWritten = 0;
BOOL result;
HANDLE pipeHandler = (HANDLE) hNamedPipe;
LPVOID buffer;
buffer = (LPVOID)LocalAlloc(LMEM_ZEROINIT, nNumberOfBytesToWrite);
(*env)->GetByteArrayRegion(env, lpBuffer, 0, nNumberOfBytesToWrite, buffer);
result = WriteFile(pipeHandler, buffer, (DWORD) nNumberOfBytesToWrite, (LPDWORD) &bytesWritten, (LPOVERLAPPED) 0);
LocalFree(buffer);
if (DEBUG)
{
printf("Native: After WriteFile BytesReadWritten %d\n", bytesWritten);
}
if (!result)
{
if (GetLastError() != ERROR_IO_PENDING)
result = 0;
else
result = 1;
}
if (!result)
{
bytesWritten = -1;
}
return bytesWritten;
}
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_FlushFileBuffers
(
JNIEnv *env,
jclass className,
jint hNamedPipe
)
{
BOOL result;
HANDLE pipeHandler = (HANDLE) hNamedPipe;
result = FlushFileBuffers(pipeHandler);
return result;
}
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_DisconnectNamedPipe
(
JNIEnv *env,
jclass className,
jint hNamedPipe
)
{
BOOL result;
HANDLE pipeHandler = (HANDLE) hNamedPipe;
result = DisconnectNamedPipe(pipeHandler);
return result;
}
JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateFile
(
JNIEnv *env,
jclass className,
jstring lpFileName,
jint dwDesiredAccess,
jint dwShareMode,
jint lpSecurityAttributes,
jint dwCreationDisposition,
jint dwFlagsAndAttributes,
jint hTemplateFile
)
{
HANDLE pipeHandler;
const jbyte *fileName;
fileName = (*env)->GetStringUTFChars(env, lpFileName, NULL);
if (fileName == NULL)
return -1;
pipeHandler = CreateFile((LPCSTR) fileName, (DWORD) dwDesiredAccess, (DWORD) dwShareMode,
(LPSECURITY_ATTRIBUTES) lpSecurityAttributes, (DWORD) dwCreationDisposition, (DWORD) dwFlagsAndAttributes, (HANDLE) hTemplateFile);
return (jint) pipeHandler;
}
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_WaitNamedPipe
(
JNIEnv *env,
jclass className,
jstring lpNamedPipeName,
jint nTimeOut
)
{
BOOL result;
const jbyte *pipeName;
pipeName = (*env)->GetStringUTFChars(env, lpNamedPipeName, NULL);
if (pipeName == NULL)
return 0;
result = WaitNamedPipe((LPCSTR) pipeName, (DWORD) nTimeOut);
return result;
}
JNIEXPORT jstring JNICALL Java_pipe_Pipe_FormatMessage
(
JNIEnv *env,
jclass className,
jint errorCode
)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = (DWORD) errorCode;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("Failed with error %d: %s"), dw, lpMsgBuf);
return (jstring) (*env)->NewStringUTF(env, lpDisplayBuf);
}
JNIEXPORT void JNICALL Java_pipe_Pipe_Print(JNIEnv *env, jclass className, jstring lpMsgBuf)
{
const jbyte *str;
str = (*env)->GetStringUTFChars(env, lpMsgBuf, NULL);
if (str == NULL)
return;
printf("Native: %s\n", str);
(*env)->ReleaseStringUTFChars(env, lpMsgBuf, str);
return;
}

109
cpp/pipe/src/pipe.h Normal file
View File

@@ -0,0 +1,109 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Pipes */
#ifndef _Included_pipe
#define _Included_pipe
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Pipes
* Method: CreateNamedPipe
* Signature: (Ljava/lang/String;IIIIIII)I
*/
JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateNamedPipe
(JNIEnv *, jclass, jstring, jint, jint, jint, jint, jint, jint, jint);
/*
* Class: Pipes
* Method: ConnectNamedPipe
* Signature: (II)Z
*/
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_ConnectNamedPipe
(JNIEnv *, jclass, jint, jint);
/*
* Class: Pipes
* Method: GetLastError
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_pipe_Pipe_GetLastError
(JNIEnv *, jclass);
/*
* Class: Pipes
* Method: CloseHandle
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_CloseHandle
(JNIEnv *, jclass, jint);
/*
* Class: Pipes
* Method: ReadFile
* Signature: (II)[B
*/
JNIEXPORT jbyteArray JNICALL Java_pipe_Pipe_ReadFile
(JNIEnv *, jclass, jint, jint);
/*
* Class: Pipes
* Method: WriteFile
* Signature: (I[BI)I
*/
JNIEXPORT jint JNICALL Java_pipe_Pipe_WriteFile
(JNIEnv *, jclass, jint, jbyteArray, jint);
/*
* Class: Pipes
* Method: FlushFileBuffers
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_FlushFileBuffers
(JNIEnv *, jclass, jint);
/*
* Class: Pipes
* Method: DisconnectNamedPipe
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_DisconnectNamedPipe
(JNIEnv *, jclass, jint);
/*
* Class: Pipes
* Method: CreateFile
* Signature: (Ljava/lang/String;IIIIII)I
*/
JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateFile
(JNIEnv *, jclass, jstring, jint, jint, jint, jint, jint, jint);
/*
* Class: Pipes
* Method: WaitNamedPipe
* Signature: (Ljava/lang/String;I)Z
*/
JNIEXPORT jboolean JNICALL Java_pipe_Pipe_WaitNamedPipe
(JNIEnv *, jclass, jstring, jint);
/*
* Class: Pipes
* Method: FormatMessage
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_pipe_Pipe_FormatMessage
(JNIEnv *, jclass, jint);
/*
* Class: Pipes
* Method: Print
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_pipe_Pipe_Print
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif

11
java/sound/.classpath Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="lib/jl1.0.1.jar"/>
<classpathentry kind="lib" path="lib/ostermillerutils-1.08.01.jar"/>
<classpathentry kind="lib" path="lib/commons-io-2.4.jar"/>
<classpathentry kind="lib" path="lib/commons-cli-1.2.jar"/>
<classpathentry kind="lib" path="lib/jid3lib-0.5.4.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

3
java/sound/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/bin
/.settings
/sound

17
java/sound/.project Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Sound</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

43
java/sound/build.xml Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="jar" name="Build file for Project Shoutcast">
<!-- All -->
<target name="all" depends="javadoc, jar, launch4j"></target>
<!-- Javadoc -->
<target name="javadoc">
<javadoc access="private" author="true" classpath="" destdir="doc" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" packagenames="mimis.exception.macro,mimis.device.network,wiiusej,mimis.application.itunes,mimis.exception.util,mimis.device.javainput,wiiusej.wiiusejevents,wiiusej.wiiusejevents.utils,mimis.util.swing,mimis.exception.worker,mimis.application.lirc,mimis.application.cmd.windows.winamp,wiiusej.values,mimis.exception.event,mimis.device.lirc.remote,mimis.device.panel,mimis.exception.device,mimis.exception.button,mimis.application.robot,mimis.application.lirc.ipod,mimis.exception.task.action,mimis.exception.application,wiiusej.wiiusejevents.wiiuseapievents,mimis.application.cmd.windows.gomplayer,mimis.application.mpc,org.wiigee.logic,mimis.device.lirc,mimis.sequence,mimis.manager,org.wiigee.util,mimis.event,mimis.application.cmd.windows.wmp,mimis.value,mimis.device.javainput.extreme3d,mimis.event.router,mimis.application.cmd,mimis.worker,org.wiigee.event,mimis.device.wiimote,mimis.device.wiimote.gesture.event,wiiusej.wiiusejevents.physicalevents,mimis.util.multiplexer,mimis,org.wiigee.control,mimis.exception.device.javainput,mimis.util,mimis.application.cmd.windows,com.dt.iTunesController,org.wiigee.device,mimis.application.vlc,mimis.device.wiimote.gesture,mimis.device.jintellitype,mimis.event.feedback,mimis.device,org.wiigee.filter,mimis.exception.application.windows,mimis.application,mimis.sequence.state,mimis.device.javainput.rumblepad,com.melloware.jintellitype,mimis.exception.event.router,mimis.exception.task,mimis.exception" source="1.6" sourcepath="src" splitindex="true" use="true" version="true" />
</target>
<!-- Jar -->
<target name="jar">
<property name="jar.dir" value="." />
<jar destfile="${jar.dir}/stream.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="udp.StreamClient" />
<attribute name="Class-Path" value="." />
</manifest>
<fileset dir="bin" />
<!--zipfileset excludes="META-INF/*.SF" src="lib/commons-logging-1.1.1.jar" /-->
</jar>
<!--copy todir="${jar.dir}">
<fileset dir=".">
<include name="*.dll" />
<include name="*.exe" />
</fileset>
</copy-->
</target>
<!-- Launch4j -->
<target name="launch4j" depends="jar">
<property name="launch4j.dir" location="C:\Program Files (x86)\Launch4j" />
<path id="launch4j">
<pathelement location="${launch4j.dir}/launch4j.jar" />
<pathelement location="${launch4j.dir}/lib/xstream.jar" />
</path>
<taskdef name="launch4j" classname="net.sf.launch4j.ant.Launch4jTask">
<classpath refid="launch4j" />
</taskdef>
<launch4j configFile="launch4j.xml" />
<delete file="launch4j.log" />
</target>
</project>

BIN
java/sound/lame.exe Normal file

Binary file not shown.

22
java/sound/launch4j.xml Normal file
View File

@@ -0,0 +1,22 @@
<launch4jConfig>
<dontWrapJar>false</dontWrapJar>
<headerType>gui</headerType>
<jar>stream.jar</jar>
<outfile>stream.exe</outfile>
<errTitle></errTitle>
<cmdLine></cmdLine>
<chdir></chdir>
<priority>normal</priority>
<downloadUrl>http://java.com/download</downloadUrl>
<supportUrl></supportUrl>
<customProcName>false</customProcName>
<stayAlive>false</stayAlive>
<manifest></manifest>
<icon></icon>
<jre>
<path></path>
<minVersion>1.6.0</minVersion>
<maxVersion></maxVersion>
<jdkPreference>preferJre</jdkPreference>
</jre>
</launch4jConfig>

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
java/sound/lib/jl1.0.1.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
java/sound/libgomp-1.dll Normal file

Binary file not shown.

BIN
java/sound/libmad.dll Normal file

Binary file not shown.

BIN
java/sound/libmp3lame.dll Normal file

Binary file not shown.

BIN
java/sound/pipe.dll Normal file

Binary file not shown.

BIN
java/sound/play.exe Normal file

Binary file not shown.

BIN
java/sound/pthreadgc2.dll Normal file

Binary file not shown.

BIN
java/sound/sox.exe Normal file

Binary file not shown.

BIN
java/sound/soxi.exe Normal file

Binary file not shown.

View File

@@ -0,0 +1,186 @@
package old;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.worker.Worker;
import com.Ostermiller.util.CircularByteBuffer;
public class Converter extends Worker {
public static final String COMMAND = "lame --mp3input --cbr %s - - --quiet";
public static final int BYTES = 4096; // bytes
public static final int BUFFER = 30000; // milliseconds
public static final int BUFFERING = 1000; // milliseconds
protected int targetRate;
protected int rate;
protected int buffer;
protected boolean convert;
protected Process process;
protected InputStream sourceInputStream, processInputStream, inputStream;
protected OutputStream processOutputStream;
protected CircularByteBuffer circularByteBuffer;
protected BufferWorker bufferWorker;
public Converter(InputStream inputStream) {
this(inputStream, -1);
}
public Converter(InputStream inputStream, int targetRate) {
this.sourceInputStream = inputStream;
this.targetRate = targetRate;
bufferWorker = new BufferWorker();
convert = false;
}
public void exit() {
super.exit();
bufferWorker.exit();
}
public synchronized void activate() throws ActivateException {
/* Read bitrate */
BufferedInputStream bufferedInputStream = new BufferedInputStream(sourceInputStream);
Bitstream bitStream = new Bitstream(bufferedInputStream);
try {
rate = bitStream.readFrame().bitrate() / 1000;
buffer = BUFFER * rate / 8;
} catch (BitstreamException e) {
log.error(e);
throw new ActivateException();
}
/* Check for need to convert */
if (targetRate < 0 || rate == targetRate) {
log.debug("No conversion required");
inputStream = sourceInputStream;
} else {
log.debug("Converting from " + rate + "kbps to " + targetRate + "kbps");
try {
String command = String.format(COMMAND, rate > targetRate ? "-B " + targetRate : "-F -b " + targetRate);
log.debug("Starting process: " + command);
process = Runtime.getRuntime().exec(command);
processInputStream = process.getInputStream();
processOutputStream = process.getOutputStream();
/* Buffer output */
circularByteBuffer = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE);
inputStream = circularByteBuffer.getInputStream();
bufferWorker.start();
convert = true;
} catch (IOException e) {
log.error(e);
throw new ActivateException();
}
}
super.activate();
notifyAll();
}
protected void deactivate() throws DeactivateException {
super.deactivate();
try {
sourceInputStream.close();
bufferWorker.stop();
if (convert) {
circularByteBuffer.clear();
convert = false;
}
inputStream.close();
} catch (IOException e) {
log.error(e);
throw new DeactivateException();
}
}
protected void work() {
if (!convert) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
log.error(e);
}
return;
}
byte[] bytes = new byte[BYTES];
int read = 0;
try {
log.debug("Writing input to process");
while ((read = sourceInputStream.read(bytes)) > 0 && !deactivate) {
/* Limit buffer size */
while (inputStream.available() > buffer) {
int progress = (int) ((1 - (inputStream.available() - buffer) / (float) buffer) * 100);
log.trace("Waiting for buffer to empty: " + progress + "%");
sleep(BUFFERING);
}
processOutputStream.write(bytes, 0, read);
}
processOutputStream.close();
log.debug("Stopped writing input to process");
process.waitFor();
log.debug("Process finished");
} catch (IOException e) {
} catch (InterruptedException e) {
log.error(e);
}
stop();
}
public synchronized InputStream getInputStream() {
if (!active()) {
if (!activate) {
start();
}
try {
wait();
} catch (InterruptedException e) {
log.error(e);
}
}
return inputStream;
}
public synchronized void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
class BufferWorker extends Worker {
protected void work() {
byte[] bytes = new byte[BYTES];
int read = 0;
try {
OutputStream bufferOutputStream = circularByteBuffer.getOutputStream();
log.debug("Start buffering process output");
while ((read = processInputStream.read(bytes, 0, BYTES)) > 0) {
bufferOutputStream.write(bytes, 0, read);
}
log.debug("Finished buffering process output");
bufferOutputStream.close();
} catch (IOException e) {}
stop();
}
}
public static void main(String[] args) {
Mp3 mp3 = new Mp3(new File("stream.mp3"), 128);
InputStream inputStream = mp3.getInputStream();
/* Play */
//Utils.play(inputStream);
/* Write to file */
Utils.write(inputStream, new File("output.mp3"));
mp3.exit();
}
}

View File

@@ -0,0 +1,198 @@
package old;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Scanner;
import mimis.exception.worker.ActivateException;
import mimis.worker.Worker;
import com.Ostermiller.util.BufferOverflowException;
import com.Ostermiller.util.CircularByteBuffer;
import com.Ostermiller.util.CircularObjectBuffer;
public class List extends Worker {
public static final int STEP = 80; // milliseconds
public static final int RATE = 192; // kbps
public static final int OVERLAP = 20000; // milliseconds
protected File file;
protected String[] fileArray;
protected int rate;
protected int chunk;
protected int overlap;
protected byte[] bytes;
protected boolean next;
protected Mp3 mp3, nextMp3;
protected InputStream mp3InputStream;
protected OutputStream audioOutputStream;
protected CircularByteBuffer circularByteBuffer;
protected CircularObjectBuffer<String> circularStringBuffer;
public List(File file) {
this(file, RATE);
}
public List(File file, int rate) {
this.file = file;
this.rate = rate;
chunk = STEP * rate / 8;
overlap = OVERLAP * RATE / 8;
bytes = new byte[chunk];
next = true;
}
public void exit() {
super.exit();
if (mp3 != null) {
mp3.exit();
}
if (nextMp3 != null) {
nextMp3.exit();
}
}
protected synchronized void activate() throws ActivateException {
try {
Scanner scanner = new Scanner(file);
ArrayList<String> fileList = new ArrayList<String>();
while (scanner.hasNextLine()) {
fileList.add(scanner.nextLine());
}
if (fileList.size() > 0) {
fileArray = fileList.toArray(new String[0]);
circularByteBuffer = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE);
audioOutputStream = circularByteBuffer.getOutputStream();
circularStringBuffer = new CircularObjectBuffer<String>(CircularByteBuffer.INFINITE_SIZE);
setNext();
super.activate();
notifyAll();
return;
}
} catch (FileNotFoundException e) {
log.error(e);
}
throw new ActivateException();
}
protected synchronized void work() {
try {
int left = chunk;
while (left > 0) {
/* Check for need to load next mp3 */
int available = mp3InputStream == null ? -1 : mp3InputStream.available();
boolean expect = mp3 == null ? false : mp3.active();
/* Act when no more data is expected */
if (!expect) {
if (available < overlap) {
setNext();
next = false;
nextMp3.start();
}
if (available < 1) {
swap();
}
}
/* Transfer data */
int read = mp3InputStream.read(bytes, 0, left);
left -= read;
audioOutputStream.write(bytes, 0, read);
}
} catch (IOException e) {
/* Swap to next if stream has stopped */
setNext();
swap();
} catch (IllegalStateException e) {
log.error(e);
}
sleep(STEP);
}
protected File getRandomFile() {
return new File(fileArray[(int) (Math.random() * fileArray.length)]);
}
public synchronized void setNext() {
if (nextMp3 == null) {
log.debug("Initialize next mp3");
nextMp3 = new Mp3(getRandomFile(), rate);
} else if (next) {
log.debug("Load next mp3");
nextMp3.setFile(getRandomFile());
}
}
public synchronized void next() {
log.debug("Stop current mp3");
mp3.stop();
}
public void swap() {
log.debug("Swap to next mp3");
Mp3 swapMp3 = mp3;
mp3 = nextMp3;
nextMp3 = swapMp3;
next = true;
/* Swap stream and announce title */
mp3InputStream = mp3.getInputStream();
try {
circularStringBuffer.write(mp3.getTitle());
} catch (BufferOverflowException e) {
log.error(e);
} catch (IllegalStateException e) {
log.error(e);
} catch (InterruptedException e) {
log.error(e);
}
}
public synchronized InputStream getInputStream() {
if (circularByteBuffer == null) {
start();
try {
wait();
} catch (InterruptedException e) {
log.error(e);
}
}
return circularByteBuffer.getInputStream();
}
public synchronized CircularObjectBuffer<String> getMetaBuffer() {
if (circularStringBuffer == null) {
start();
try {
wait();
} catch (InterruptedException e) {
log.error(e);
}
}
return circularStringBuffer;
}
public static void main(String[] args) {
int rate = 192;
List list = new List(new File("mp3"), rate);
/*Shoutcast shoutcast = new Shoutcast(null, rate, 9876);
shoutcast.start();
shoutcast.setInputStream(list.getInputStream());
shoutcast.setMetaBuffer(list.getMetaBuffer());*/
while (true) {
try {
Thread.sleep(15000);
list.next();
} catch (InterruptedException e) {}
}
}
}

View File

@@ -0,0 +1,79 @@
package old;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import mimis.exception.worker.ActivateException;
import org.farng.mp3.MP3File;
import org.farng.mp3.TagException;
public class Mp3 extends Converter {
protected File file;
protected String title;
public Mp3(File file) {
this(file, -1);
}
public Mp3(File file, int targetRate) {
super(null, targetRate);
setFile(file);
title = "";
}
public synchronized void activate() throws ActivateException {
/* Open file */
try {
sourceInputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
log.error(e);
throw new ActivateException();
}
/* Read ID3V2 tags */
try {
MP3File mp3File = new MP3File(file);
String album = clean(mp3File.getID3v2Tag().getAlbumTitle());
String artist = clean(mp3File.getID3v2Tag().getLeadArtist());
String track = clean(mp3File.getID3v2Tag().getSongTitle());
if (album.isEmpty()) {
title = String.format("%s - %s", artist, track, album);
} else {
title = String.format("%s - %s {%s}", artist, track, album);
}
log.debug("Title: " + title);
} catch (IOException e) {
log.error(e);
} catch (TagException e) {
log.error(e);
}
try {
sourceInputStream.skip(100000);
} catch (IOException e) {}
super.activate();
}
protected String clean(String input) {
String output = input.replace("\0", "");
return output.replace("<EFBFBD><EFBFBD>", "");
}
public String getTitle() {
return title;
}
public void setFile(File file) {
this.file = file;
}
public static void main(String[] args) {
final Mp3 mp3 = new Mp3(new File("input.mp3"), 128);
Utils.write(mp3.getInputStream(), new File("one.mp3"));
mp3.setFile(new File("stream.mp3"));
Utils.write(mp3.getInputStream(), new File("two.mp3"));
mp3.exit();
}
}

View File

@@ -0,0 +1,42 @@
package old;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;
public class Utils {
public static final int BUFFER = 2048; // bytes
public static void play(InputStream inputStream) {
try {
Thread.sleep(5000);
new Player(new BufferedInputStream(inputStream)).play();
} catch (JavaLayerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void write(InputStream inputStream, File file) {
byte[] bytes = new byte[BUFFER];
int read = 0;
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
while ((read = inputStream.read(bytes)) > 0) {
fileOutputStream.write(bytes, 0, read);
}
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,8 @@
package sound;
public interface Consumer {
public void start(Producer producer);
public void start();
public void stop();
public void exit();
}

View File

@@ -0,0 +1,13 @@
package sound;
import javax.sound.sampled.AudioFormat;
public interface Format extends Cloneable {
public interface Standard extends Format {
public AudioFormat getAudioFormat();
}
public interface Mp3 extends Format {
public int getRate();
}
}

View File

@@ -0,0 +1,76 @@
package sound;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class GreedyInputStream extends BufferedInputStream {
protected Log log = LogFactory.getLog(getClass());
protected static final int SLEEP = 500;
protected static final int BUFFER_SIZE = 30000; // in bytes
protected static final int MINIMUM_SIZE = 1000; // in bytes
protected int bufferSize;
protected int minimumSize;
protected boolean hoard;
public GreedyInputStream(InputStream inputStream) {
this(inputStream, BUFFER_SIZE, MINIMUM_SIZE);
}
public GreedyInputStream(InputStream inputStream, int bufferSize) {
super(inputStream, bufferSize);
this.bufferSize = bufferSize;
hoard = true;
}
public GreedyInputStream(InputStream inputStream, int bufferSize, int minimumSize) {
this(inputStream, bufferSize);
this.minimumSize = minimumSize;
}
public int read() throws IOException {
hoard();
byte[] buffer = new byte[1];
in.read(buffer, 0, 1);
return (int) buffer[0];
}
public int read(byte[] buffer, int offset, int length) throws IOException {
hoard();
in.read(buffer, offset, length);
return length;
}
public void hoard() throws IOException {
int available = available();
if (hoard && available < MINIMUM_SIZE) {
long time = System.currentTimeMillis();
do {
try {
Thread.sleep(SLEEP);
} catch (InterruptedException e) {
log.warn(e);
}
} while (available() < BUFFER_SIZE);
log.debug(String.format("Buffered %d bytes in %s milliseconds", BUFFER_SIZE - available, System.currentTimeMillis() - time));
}
}
public void clear() throws IOException {
this.buf = new byte[buf.length];
reset();
}
public void drain() {
drain(true);
}
public void drain(boolean drain) {
hoard = !drain;
}
}

View File

@@ -0,0 +1,119 @@
package sound;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.sound.sampled.AudioFormat;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.worker.Worker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import sound.Format.Standard;
import sound.SoxBuilder.File;
import sound.SoxBuilder.Option;
import sound.SoxBuilder.File.Type;
public class Port extends Worker implements Consumer {
protected Log log = LogFactory.getLog(getClass());
protected static final int BUFFER_SIZE = 1024 * 4; // in bytes
protected String device;
protected Producer producer;
protected Process process;
protected InputStream producerInputStream;
protected OutputStream processOutputStream;
protected ProcessBuilder processBuilder;
public Port() {
this("0");
}
public Port(String device) {
this.device = device;
}
@SuppressWarnings("static-access")
public void start(Producer producer) {
this.producer = producer;
producerInputStream = producer.getInputStream();
String command = "";
if (producer instanceof Standard) {
AudioFormat audioFormat = ((Standard) producer).getAudioFormat();
SoxBuilder.addFile(File.setType(Type.STANDARD).setOptions(audioFormat));
} else if (producer instanceof Format.Mp3) {
SoxBuilder.addFile(File.setType(Type.STANDARD).setOption(File.Format.MP3));
}
command = SoxBuilder
.setOption(Option.QUIET)
.addFile(File.setType(Type.DEVICE))
.build();
log.debug(String.format("Build process (\"%s\")", command));
processBuilder = new ProcessBuilder(command.split(" "));
processBuilder.environment().put("AUDIODEV", device);
start(true);
}
protected void activate() throws ActivateException {
producer.start();
if (process == null) {
try {
process = processBuilder.start();
} catch (IOException e) {
log.error(e);
throw new ActivateException();
}
processOutputStream = process.getOutputStream();
}
super.activate();
}
protected void deactivate() throws DeactivateException {
super.deactivate();
try {
processOutputStream.flush();
} catch (IOException e) {
log.error(e);
throw new DeactivateException();
}
}
public void exit() {
try {
log.debug("close process output stream");
processOutputStream.close();
log.debug("wait for process to terminate");
process.waitFor();
} catch (IOException e) {
log.error(e);
} catch (InterruptedException e) {
log.error(e);
} finally {
process = null;
}
}
protected void work() {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int read = producerInputStream.read(buffer, 0, buffer.length);
if (read > 0) {
processOutputStream.write(buffer, 0, read);
} else {
exit();
}
} catch (IOException e) {
log.error(e);
exit();
}
}
}

View File

@@ -0,0 +1,10 @@
package sound;
import java.io.InputStream;
public interface Producer extends Format {
public InputStream getInputStream();
public void start();
public void stop();
public void exit();
}

View File

@@ -0,0 +1,159 @@
package sound;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.worker.Worker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Source implements Consumer {
protected Log log = LogFactory.getLog(getClass());
protected static final int BUFFER_SIZE = 1024 * 4; // in bytes
protected static final int PLAY_FRAMES = 10; // count
protected String name;
protected Producer producer;
protected InputStream producerInputStream;
protected Worker worker;
public Source(String name) throws LineUnavailableException {
this.name = name;
}
public void start() {
if (worker != null) {
worker.start(true);
}
}
public void start(Producer producer) {
this.producer = producer;
producerInputStream = producer.getInputStream();
if (worker != null) {
worker.exit();
}
if (producer instanceof Format.Standard) {
log.debug("Format.Standard");
worker = new DefaultWorker((Format.Standard) producer);
} else if (producer instanceof Format.Mp3) {
log.debug("Format.Mp3");
worker = new Mp3Worker((Format.Mp3) producer);
}
start();
}
public void stop() {
if (worker != null) {
worker.stop();
}
}
public void exit() {
if (worker != null) {
worker.exit();
}
}
protected class DefaultWorker extends Worker {
protected Format.Standard format;
protected SourceDataLine line;
public DefaultWorker(Format.Standard format) {
this.format = format;
}
public void activate() throws ActivateException {
AudioFormat audioFormat = format.getAudioFormat();
try {
if (line == null) {
line = Tool.getSourceDataLine(name, audioFormat);
}
if (!line.isOpen()) {
line.open();
}
} catch (LineUnavailableException e) {
log.error(e);
throw new ActivateException();
}
if (!line.isRunning()) {
line.start();
}
super.activate();
}
public void deactivate() throws DeactivateException {
super.deactivate();
line.flush();
}
public void exit() {
super.exit();
line.close();
}
protected void work() {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int read = producerInputStream.read(buffer, 0, buffer.length);
if (read > 0) {
line.write(buffer, 0, read);
} else {
exit();
}
} catch (IOException e) {
log.error(e);
exit();
}
}
}
protected class Mp3Worker extends Worker {
protected Format.Mp3 format;
protected Player player;
public Mp3Worker(Format.Mp3 format) {
this.format = format;
}
public void activate() throws ActivateException {
producer.start();
super.activate();
}
public void deactivate() throws DeactivateException {
super.deactivate();
producer.stop();
}
public void exit() {
super.exit();
player.close();
}
protected void work() {
try {
if (player == null) {
player = new Player(producerInputStream);
sleep(500);
}
player.play(PLAY_FRAMES);
} catch (JavaLayerException e) {
log.error(e);
}
if (player.isComplete()) {
stop();
}
}
}
}

View File

@@ -0,0 +1,322 @@
package sound;
import java.util.HashMap;
import java.util.Map.Entry;
import javax.sound.sampled.AudioFormat;
import sound.SoxBuilder.Option.Combine;
import sound.SoxBuilder.Option.Replay;
public final class SoxBuilder {
protected static SoxBuilder instance;
protected static HashMap<String, String> optionMap;
protected static String files;
protected static String effects;
static {
instance = new SoxBuilder();
reset();
}
public static void reset() {
optionMap = new HashMap<String, String>();
files = "";
effects = "";
}
public static SoxBuilder setOption(Option option, String value) {
optionMap.put(option.getCode(), value);
return instance;
}
public static SoxBuilder setOption(Option option) {
return SoxBuilder.setOption(option, "");
}
public static SoxBuilder setOption(Option option, int value) {
return SoxBuilder.setOption(option, String.valueOf(value));
}
public static SoxBuilder setOption(Option option, Combine combine) {
return SoxBuilder.setOption(option, combine.getCode());
}
public static SoxBuilder setOption(Combine combine) {
return SoxBuilder.setOption(Option.COMBINE, combine);
}
public static SoxBuilder setOption(Option option, Replay replay) {
return SoxBuilder.setOption(option, replay.toString().toLowerCase());
}
public static SoxBuilder setOption(Replay replay) {
return SoxBuilder.setOption(Option.REPLAY, replay);
}
public static SoxBuilder addFile(File file) {
files = String.format("%s %s", files, file.build());
return instance;
}
public static SoxBuilder addEffect(Effect effect) {
effects = String.format("%s %s", effects, effect.build());
return instance;
}
public String build() {
String build = "sox";
for (Entry<String, String> entry : optionMap.entrySet()) {
String value = entry.getValue();
if (value.equals("")) {
build = String.format("%s %s", build, entry.getKey());
} else {
String option = String.format("%s %s", entry.getKey(), value);
build = String.format("%s %s", build, option);
}
}
build = String.format("%s%s%s", build, files, effects);
reset();
return build;
}
public enum Environment {
AUDIODRIVER, AUDIODEV
}
public enum Option {
BUFFER ("--buffer"), // default=8192
INPUT_BUFFER ("--input-buffer"),
CLOBBER ("--clobber"),
COMBINE ("--combine"), // |Combine|
NO_DITHER ("--no-dither"), // (-D)
EFFECTS_FILE ("--efects-file"),
GUARD ("--guard"), // (-G)
MIX ("-m"), // (--combine mix)
MERGE ("-M"), // (--combine merge)
MAGIC ("--magic"),
MULTI_THREADED ("--multi-threaded"),
SINGLE_THREADED ("--single-threaded"),
NORM ("--norm"), // [=dB-level]
PLAY_RATE_ARG ("--play-rate-arg"),
QUIET ("--no-show-progress"), // (-q)
REPEATABLE ("-R"),
REPLAY ("--replay-gain"), // |Replay|
MULTIPLY ("-T"), // (--combine multiply)
TEMP ("--temp");
protected String code;
private Option(String code) {
this.code = code;
}
public String getCode() {
return code;
}
public enum Combine {
CONCATENATE ("concatenate"),
MERGE ("merge"), // (-M)
MIX ("mix"), // (-m)
MIX_POWER ("mix-power"),
MULTIPLY ("multiply"), // (-T)
SEQUENCE ("sequence");
protected String code;
private Combine(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
public enum Replay {
TRACK, ALBUM, OFF
}
}
public static class File {
protected static File instance;
protected static HashMap<String, String> optionMap;
protected static Type type;
static {
instance = new File();
reset();
}
public static void reset() {
optionMap = new HashMap<String, String>();
type = Type.PIPE;
}
public static File setOption(Option option, String value) {
optionMap.put(option.getCode(), value);
return instance;
}
public static File setOption(Option option) {
return File.setOption(option, "");
}
public static File setOption(Option option, int value) {
return File.setOption(option, String.valueOf(value));
}
public static File setOption(Option option, Encoding encoding) {
return File.setOption(option, encoding.getCode());
}
public static File setOption(Encoding encoding) {
return File.setOption(Option.ENCODING, encoding);
}
public static File setOption(Option option, Format format) {
return File.setOption(option, format.toString().toLowerCase());
}
public static File setOption( Format format) {
return File.setOption(Option.FORMAT, format);
}
public static File setOption(Option option, Endian endian) {
return File.setOption(option, endian.toString().toLowerCase());
}
public static File setOption(Endian endian) {
return File.setOption(Option.ENDIAN, endian);
}
public File setOptions(AudioFormat audioFormat) {
setOption(Option.CHANNELS, audioFormat.getChannels());
setOption(Option.RATE, String.format("%sk", String.valueOf(audioFormat.getSampleRate() / 1000f)));
AudioFormat.Encoding encoding = audioFormat.getEncoding();
int bits = audioFormat.getSampleSizeInBits();
if (encoding.equals(AudioFormat.Encoding.ALAW)) {
setOption(Format.AL);
setOption(Encoding.A_LAW);
} else if (encoding.equals(AudioFormat.Encoding.ULAW)) {
setOption(Format.UL);
setOption(Encoding.U_LAW);
} else if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED)) {
setOption(Format.valueOf(String.format("S%d", bits)));
setOption(Encoding.SIGNED_INTEGER);
} else if (encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
setOption(Format.valueOf(String.format("U%d", bits)));
setOption(Encoding.UNSIGNED_INTEGER);
}
setOption(audioFormat.isBigEndian() ? Endian.BIG : Endian.LITTLE);
return instance;
}
public static File setType(Type type) {
File.type = type;
return instance;
}
public String build() {
String build = type.getCode();
for (Entry<String, String> entry : optionMap.entrySet()) {
String value = entry.getValue();
if (value.equals("")) {
build = String.format("%s %s", entry.getKey(), build);
} else {
String option = String.format("%s %s", entry.getKey(), value);
build = String.format("%s %s", option, build);
}
}
reset();
return build;
}
public enum Option {
BITS ("--bits"), // (-b)
CHANNELS ("--channels"), // (-c)
ENCODING ("--encoding"), // (-e), |Encoding|
NO_GLOB ("--no-glob"),
RATE ("--rate"), // (-r)
FORMAT ("--type"), // (-t), |Format|
ENDIAN ("--endian"), // (-L, -B, -x), |Endian|
REVERSE_NIBBLES ("--reverse-nibbles"), // (-N)
REVERSE_BITS ("--reverse-bits"), // (-X)
/* Input only */
IGNORE_LENGTH ("--ignore-length"),
VOLUME ("--volume"), // (-v)
/* Output only */
ADD_COMMENT ("--add-comment"),
COMMENT ("--comment"),
COMMENT_FILE ("--comment-file"),
COMPRESSION ("--compression"); // -C
protected String code;
private Option(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
public enum Encoding {
SIGNED_INTEGER ("signed-integer"), // PCM data stored as signed integers
UNSIGNED_INTEGER ("unsigned-integer"), // PCM data stored as unsigned integers
FLOATING_POINT ("floating-point"), // PCM data stored as single precision (32-bit) or double precision (64-bit) floating-point numbers
A_LAW ("a-lawW"), // International telephony standard for logarithmic encoding to 8 bits per sample (~13-bit PCM)
U_LAW ("u-law"), // North American telephony standard for logarithmic encoding to 8 bits per sample (~14-bit PCM)
MU_LAW ("mu-law"), // alias for u-law (~14-bit PCM)
OKI_ADPCM ("oki-adpcm"), // OKI (VOX, Dialogic or Intel) 4-bit ADPCM (~12-bit PCM)
IMA_ADPCM ("ima-adpcm"), // IMA (DVI) 4-bit ADPCM (~13-bit PCM)
MS_ADPCM ("ms-adpcm"), // Microsoft 4-bit ADPCM (~14-bit PCM)
GSM_FULL_RATE ("gsm-full-rate"); // Several audio formats used for digital wireless telephone calls
protected String code;
private Encoding(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
public enum Format {
AIF, AIFC, AIFF, AIFFC, AL, AMB, AMR, ANY, ARL, AU, AVR, BIN, CAF, CDDA, CDR, CVS, CVSD, CVU, DAT, DVMS, EDU, F32, F64, FAP, FLAC, FSSD, GSM, GSRT, HCOM, HTK, IMA, IRCAM, LA, LPC, LPC10, LU, M3U, M4A, MAT, MAT4, MAT5, MAUD, MP2, MP3, MP4, NIST, OGG, PAF, PLS, PRC, PVF, RAW, S16, S24, S32, S8, SD2, SDS, SF, SLN, SMP, SND, SNDR, SNDT, SOU, SOX, SPH, TXW, U16, U24, U32, U8, UL, VMS, VOC, VORBIS, VOX, W64, WAV, WAVPCM, WV, WVE, XA, XI;
}
public enum Endian {
LITTLE, BIG, SWAP;
}
public enum Type {
STANDARD ("-"), // -t must be given
PIPE ("-p"), // (--sox-pipe)
DEVICE ("-d"), // (--default-device)
NULL ("-n"); // (--null)
protected String code;
private Type(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
}
public class Effect {
public String build() {
return null;
}
}
}

View File

@@ -0,0 +1,195 @@
package sound;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.URL;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.worker.Worker;
import com.Ostermiller.util.CircularByteBuffer;
import com.Ostermiller.util.CircularObjectBuffer;
public class Stream extends Worker implements Producer, Format.Mp3 {
public static final String HTTP = "http://shoutcast.omroep.nl:8104/";
public static final int STEP = 80; // in milliseconds
protected String http;
protected Socket socket;
protected InputStream socketInputStream;
protected OutputStreamWriter socketOutputStreamWriter;
protected GreedyInputStream greedyInputStream;
protected int meta;
protected int rate;
protected int chunk;
protected int untilMeta;
protected CircularByteBuffer audioCircularByteBuffer;
protected CircularObjectBuffer<String> metaCircularObjectBuffer;
protected String metaData;
public Stream() {
this(HTTP);
}
public Stream(String http) {
super(true);
this.http = http;
meta = -1;
rate = -1;
audioCircularByteBuffer = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE);
metaCircularObjectBuffer = new CircularObjectBuffer<String>();
}
protected void connect(URL url) {
try {
/* Open socket communication */
socket = new Socket(url.getHost(), url.getPort());
socketInputStream = socket.getInputStream();
socketOutputStreamWriter = new OutputStreamWriter(socket.getOutputStream());
/* Write stream request */
socketOutputStreamWriter.write("GET " + url.getFile() + " HTTP/1.1\r\n");
socketOutputStreamWriter.write("Host: " + url.getHost() + "\r\n");
socketOutputStreamWriter.write("Icy-MetaData: 1\r\n");
socketOutputStreamWriter.write("Connection: close\r\n");
socketOutputStreamWriter.write("\r\n");
socketOutputStreamWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
protected void activate() throws ActivateException {
try {
/* Initialize connection */
URL url = new URL(http);
/* Parse headers */
connect(url);
InputStreamReader inputStreamReader = new InputStreamReader(socketInputStream);
StringBuffer stringBuffer = new StringBuffer();
char character;
int skip = 0;
while ((character = (char) inputStreamReader.read()) > 0) {
++skip;
if (character == '\n') {
/* Fetch relevant headers */
String line = stringBuffer.toString().trim();
if (line.startsWith("icy-metaint")) {
meta = Integer.valueOf(line.substring(line.indexOf(":") + 1).trim());
} else if (line.startsWith("icy-br")) {
rate = Integer.valueOf(line.substring(line.indexOf(":") + 1).trim());
} else if (line.equals("")) {
break;
}
stringBuffer = new StringBuffer();
} else {
stringBuffer.append(character);
}
}
inputStreamReader.close();
/* Reconnect to bypass pre-buffering problems */
connect(url);
socketInputStream = socket.getInputStream();
socketInputStream.skip(skip);
} catch (IOException e) {
e.printStackTrace();
} catch (NumberFormatException e) {
e.printStackTrace();
}
/* Calculate streaming parameters */
untilMeta = meta;
chunk = STEP * rate / 8;
super.activate();
}
public void deactivate() throws DeactivateException {
super.deactivate();
audioCircularByteBuffer.clear();
metaCircularObjectBuffer.clear();
try {
greedyInputStream.clear();
} catch (IOException e) {
log.error(e);
throw new DeactivateException();
}
}
protected void work() {
int left = chunk;
/* Handle media at appropriate times */
while (meta > 0 && left >= untilMeta) {
stream(untilMeta);
meta();
left -= untilMeta;
untilMeta = meta;
}
/* Stream at fixed rate */
stream(left);
untilMeta -= left;
sleep(STEP);
}
protected void stream(int length) {
try {
byte[] bytes = new byte[length];
int read = 0;
while (length > 0 && (read = socketInputStream.read(bytes)) > 0) {
length -= read;
audioCircularByteBuffer.getOutputStream().write(bytes);
}
} catch (IOException e) {
log.error(e);
stop();
}
}
protected void meta() {
try {
/* Retrieve data length */
byte[] data = new byte[1];
socketInputStream.read(data);
int length = 16 * data[0];
data = new byte[length];
socketInputStream.read(data);
/* Check for new data */
String newMetaData = new String(data);
if (!newMetaData.isEmpty() && !newMetaData.equals(metaData)) {
metaData = newMetaData;
metaCircularObjectBuffer.write(new String(data));
log.debug("data: " + metaData);
}
return;
} catch (IOException e) {
log.error(e);
} catch (IllegalStateException e) {
log.error(e);
} catch (InterruptedException e) {
log.error(e);
}
stop();
}
public InputStream getInputStream() {
greedyInputStream = new GreedyInputStream(audioCircularByteBuffer.getInputStream());
return greedyInputStream;
}
public CircularObjectBuffer<String> getMetaBufferStream() {
return metaCircularObjectBuffer;
}
public int getRate() {
return rate;
}
}

View File

@@ -0,0 +1,91 @@
package sound;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Target implements Producer, Format.Standard {
protected Log log = LogFactory.getLog(getClass());
protected Standard format;
protected TargetDataLine line;
protected InputStream targetInputStream;
protected AudioFormat audioFormat;
public Target(String name) throws LineUnavailableException {
log.debug(String.format("Target \"%s\" without format", name));
line = Tool.getTargetDataLine(name);
audioFormat = line.getFormat();
targetInputStream = new TargetInputStream();
}
public Target(String name, AudioFormat audioFormat) throws LineUnavailableException {
log.debug(String.format("Target \"%s\" with format: %s", name, audioFormat));
this.audioFormat = audioFormat;
line = Tool.getTargetDataLine(name, audioFormat);
targetInputStream = new TargetInputStream();
}
public AudioFormat getAudioFormat() {
return audioFormat;
}
public InputStream getInputStream() {
return targetInputStream;
}
public class TargetInputStream extends InputStream {
protected boolean open;
public TargetInputStream() {
open = false;
}
public int read() throws IOException {
start();
byte[] buffer = new byte[1];
line.read(buffer, 0, 1);
return (int) buffer[0];
}
public int read(byte[] buffer, int offset, int length) {
start();
line.read(buffer, offset, length);
return length;
}
public int available() {
start();
return line.available();
}
}
public void start() {
if (!line.isOpen()) {
try {
line.open();
} catch (LineUnavailableException e) {
log.error(e);
}
}
if (!line.isRunning()) {
line.start();
}
}
public void stop() {
line.flush();
}
public void exit() {
line.close();
}
}

View File

@@ -0,0 +1,27 @@
package sound;
import javax.sound.sampled.AudioFormat;
public class Test {
public static void main(String[] args) {
AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 48000f, 16, 2, 4, 48000f, true);
try {
Producer p1 = new Target("Line-In (Creative SB X-Fi)");
Producer p2 = new Target("Line 1 (Virtual Audio Cable)", audioFormat);
Producer p3 = new Stream("http://ics2gss.omroep.nl:80/3fm-bb-mp3");
Consumer c1 = new Source("Java Sound Audio Engine");
Consumer c2 = new Port("Speakers (Creative SB X-Fi)");
c2.start(p3);
/*while (true) {
Thread.sleep(3000);
c2.stop();
Thread.sleep(1000);
c2.start();
}*/
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,140 @@
package sound;
import java.util.ArrayList;
import java.util.HashMap;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Port;
import javax.sound.sampled.Port.Info;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Tool {
protected static Log log = LogFactory.getLog(Tool.class);
protected static HashMap<String, Device<TargetDataLine>> targetMap;
protected static HashMap<String, Device<SourceDataLine>> sourceMap;
protected static ArrayList<String> portList;
protected static ArrayList<String> targetList;
protected static ArrayList<String> sourceList;
static {
Tool tool = new Tool();
targetMap = new HashMap<String, Device<TargetDataLine>>();
sourceMap = new HashMap<String, Device<SourceDataLine>>();
targetList = new ArrayList<String>();
sourceList = new ArrayList<String>();
portList = new ArrayList<String>();
for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) {
String name = mixerInfo.getName();
Mixer mixer = AudioSystem.getMixer(mixerInfo);
for (Line.Info lineInfo : mixer.getSourceLineInfo()) {
String lineClassName = lineInfo.getLineClass().getName();
if (lineClassName.equals("javax.sound.sampled.SourceDataLine")) {
if (mixer.isLineSupported(lineInfo)) {
log.debug("<Source> " + name);
sourceMap.put(name, tool.new Device<SourceDataLine>(mixer, lineInfo));
}
}
}
for (Line.Info lineInfo : mixer.getTargetLineInfo()) {
String lineClassName = lineInfo.getLineClass().getName();
if (lineClassName.equals("javax.sound.sampled.TargetDataLine")) {
if (mixer.isLineSupported(lineInfo)) {
log.debug("<Target> " + name);
targetMap.put(name, tool.new Device<TargetDataLine>(mixer, lineInfo));
}
} else if (lineClassName.equals("javax.sound.sampled.Port")) {
name = name.substring(5);
try {
Port port = (Port) mixer.getLine(lineInfo);
Port.Info portInfo = (Info) port.getLineInfo();
if (!targetMap.containsKey(name) || portInfo.equals(Port.Info.LINE_OUT) || portInfo.equals(Port.Info.SPEAKER)) {
log.debug("<Port> " + name);
portList.add(name);
}
} catch (LineUnavailableException e) {
log.error(e);
}
}
}
}
}
public static String[] getTargets() {
return targetMap.keySet().toArray(new String[0]);
}
public static String[] getSources() {
return sourceMap.keySet().toArray(new String[0]);
}
public static String[] getPorts() {
return portList.toArray(new String[0]);
}
public static TargetDataLine getTargetDataLine(String name) throws LineUnavailableException {
if (targetMap.containsKey(name)) {
return targetMap.get(name).getLine();
} else {
throw new LineUnavailableException();
}
}
public static TargetDataLine getTargetDataLine(String name, AudioFormat audioFormat) throws LineUnavailableException {
if (targetMap.containsKey(name)) {
return targetMap.get(name).getLine(audioFormat);
} else {
throw new LineUnavailableException();
}
}
public static SourceDataLine getSourceDataLine(String name) throws LineUnavailableException {
if (sourceMap.containsKey(name)) {
return sourceMap.get(name).getLine();
} else {
throw new LineUnavailableException();
}
}
public static SourceDataLine getSourceDataLine(String name, AudioFormat audioFormat) throws LineUnavailableException {
if (sourceMap.containsKey(name)) {
return sourceMap.get(name).getLine(audioFormat);
} else {
throw new LineUnavailableException();
}
}
public class Device<T> {
protected Mixer mixer;
protected Line.Info lineInfo;
public Device(Mixer mixer, Line.Info lineInfo) {
this.mixer = mixer;
this.lineInfo = lineInfo;
}
@SuppressWarnings("unchecked")
public T getLine() throws LineUnavailableException {
return (T) mixer.getLine(lineInfo);
}
@SuppressWarnings("unchecked")
public T getLine(AudioFormat audioFormat) throws LineUnavailableException {
DataLine.Info dataLineInfo = new DataLine.Info(lineInfo.getLineClass(), audioFormat);
return (T) mixer.getLine(dataLineInfo);
}
}
}

View File

@@ -0,0 +1,43 @@
package sound;
import java.io.InputStream;
public class Transducer implements Consumer, Producer {
public int rate;
public Transducer(Producer producer) {
//setProducer(producer);
}
public int getRate() {
return rate;
}
public InputStream getInputStream() {
// TODO Auto-generated method stub
return null;
}
public void start(Producer producer) {
// TODO Auto-generated method stub
}
@Override
public void start() {
// TODO Auto-generated method stub
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void exit() {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,55 @@
package test;
import javax.sound.sampled.*;
public class SoundAudit {
public static void main(String[] args) { try {
System.out.println("OS: "+System.getProperty("os.name")+" "+
System.getProperty("os.version")+"/"+
System.getProperty("os.arch")+"\nJava: "+
System.getProperty("java.version")+" ("+
System.getProperty("java.vendor")+")\n");
for (Mixer.Info thisMixerInfo : AudioSystem.getMixerInfo()) {
System.out.println("Mixer: "+thisMixerInfo.getDescription()+
" ["+thisMixerInfo.getName()+"]");
Mixer thisMixer = AudioSystem.getMixer(thisMixerInfo);
for (Line.Info thisLineInfo:thisMixer.getSourceLineInfo()) {
if (thisLineInfo.getLineClass().getName().equals(
"javax.sound.sampled.Port")) {
Line thisLine = thisMixer.getLine(thisLineInfo);
thisLine.open();
System.out.println(" Source Port: "
+thisLineInfo.toString());
for (Control thisControl : thisLine.getControls()) {
System.out.println(AnalyzeControl(thisControl));}
thisLine.close();}}
for (Line.Info thisLineInfo:thisMixer.getTargetLineInfo()) {
if (thisLineInfo.getLineClass().getName().equals(
"javax.sound.sampled.Port")) {
Line thisLine = thisMixer.getLine(thisLineInfo);
thisLine.open();
System.out.println(" Target Port: "
+thisLineInfo.toString());
for (Control thisControl : thisLine.getControls()) {
System.out.println(AnalyzeControl(thisControl));}
thisLine.close();}}}
} catch (Exception e) {e.printStackTrace();}}
public static String AnalyzeControl(Control thisControl) {
String type = thisControl.getType().toString();
if (thisControl instanceof BooleanControl) {
return " Control: "+type+" (boolean)"; }
if (thisControl instanceof CompoundControl) {
System.out.println(" Control: "+type+
" (compound - values below)");
String toReturn = "";
for (Control children:
((CompoundControl)thisControl).getMemberControls()) {
toReturn+=" "+AnalyzeControl(children)+"\n";}
return toReturn.substring(0, toReturn.length()-1);}
if (thisControl instanceof EnumControl) {
return " Control:"+type+" (enum: "+thisControl.toString()+")";}
if (thisControl instanceof FloatControl) {
return " Control: "+type+" (float: from "+
((FloatControl) thisControl).getMinimum()+" to "+
((FloatControl) thisControl).getMaximum()+")";}
return " Control: unknown type";}
}

View File

@@ -0,0 +1,29 @@
package test.lines;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.TargetDataLine;
public class Main {
public static void main(String[] args) {
System.out.println(System.getProperty("javax.sound.sampled.SourceDataLine"));
new AudioFormat(44100, 16, 2, true, false);
for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) {
Mixer mixer = AudioSystem.getMixer(mixerInfo);
for (Line.Info lineInfo : mixer.getTargetLineInfo()) {
try {
Line line = mixer.getLine(lineInfo);
if (mixer.isLineSupported(lineInfo) && line instanceof TargetDataLine) {
new TargetLine(mixer, (TargetDataLine) line);
}
} catch (LineUnavailableException e) {}
}
}
}
}

View File

@@ -0,0 +1,19 @@
package test.lines;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
public class SourceLine {
//private Mixer mixer;
private SourceDataLine line;
public SourceLine(Mixer mixer, SourceDataLine line) {
//this.mixer = mixer;
this.line = line;
System.out.println("SOURCE " + mixer.getMixerInfo().getName() + " || " + line.getLineInfo());
}
public int write(byte[] bytes, int offset, int length) {
return line.write(bytes, offset, length);
}
}

View File

@@ -0,0 +1,19 @@
package test.lines;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.TargetDataLine;
public class TargetLine {
//private Mixer mixer;
private TargetDataLine line;
public TargetLine(Mixer mixer, TargetDataLine line) {
//this.mixer = mixer;
this.line = line;
System.out.println("TARGET " + mixer.getMixerInfo().getName() + " || " + line.getLineInfo());
}
public int read(byte[] bytes, int offset, int length) {
return line.read(bytes, offset, length);
}
}

1
java/sound/stream.bat Normal file
View File

@@ -0,0 +1 @@
java -classpath bin udp.StreamClient 234.5.6.7 4567

BIN
java/sound/stream.exe Normal file

Binary file not shown.

BIN
java/sound/stream.jar Normal file

Binary file not shown.

13
java/sound/txt/keuze.txt Normal file
View File

@@ -0,0 +1,13 @@
from pcm:
-r -s <freq in khz> [--unsigned] [--big-endian]
to mp3:
--cbr -b <bitrate>
mp3 to pcm:
--decode
always:
- - --quiet

1357
java/sound/txt/mp3 Normal file

File diff suppressed because it is too large Load Diff

182
java/sound/txt/options Normal file
View File

@@ -0,0 +1,182 @@
LAME 32bits version 3.98.4 (http://www.mp3dev.org/)
usage: lame [options] <infile> [outfile]
<infile> and/or <outfile> can be "-", which means stdin/stdout.
RECOMMENDED:
lame -V2 input.wav output.mp3
OPTIONS:
Input options:
--scale <arg> scale input (multiply PCM data) by <arg>
--scale-l <arg> scale channel 0 (left) input (multiply PCM data) by <arg>
--scale-r <arg> scale channel 1 (right) input (multiply PCM data) by <arg>
--mp1input input file is a MPEG Layer I file
--mp2input input file is a MPEG Layer II file
--mp3input input file is a MPEG Layer III file
--nogap <file1> <file2> <...>
gapless encoding for a set of contiguous files
--nogapout <dir>
output dir for gapless encoding (must precede --nogap)
--nogaptags allow the use of VBR tags in gapless encoding
Input options for RAW PCM:
-r input is raw pcm
-x force byte-swapping of input
-s sfreq sampling frequency of input file (kHz) - default 44.1 kHz
--bitwidth w input bit width is w (default 16)
--signed input is signed (default)
--unsigned input is unsigned
--little-endian input is little-endian (default)
--big-endian input is big-endian
Operational options:
-a downmix from stereo to mono file for mono encoding
-m <mode> (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono
default is (j) or (s) depending on bitrate
joint = joins the best possible of MS and LR stereo
simple = force LR stereo on all frames
force = force MS stereo on all frames.
--preset type type must be "medium", "standard", "extreme", "insane",
or a value for an average desired bitrate and depending
on the value specified, appropriate quality settings will
be used.
"--preset help" gives more info on these
--comp <arg> choose bitrate to achive a compression ratio of <arg>
--replaygain-fast compute RG fast but slightly inaccurately (default)
--replaygain-accurate compute RG more accurately and find the peak sample
--noreplaygain disable ReplayGain analysis
--clipdetect enable --replaygain-accurate and print a message whether
clipping occurs and how far the waveform is from full scale
--flush flush output stream as soon as possible
--freeformat produce a free format bitstream
--decode input=mp3 file, output=wav
-t disable writing wav header when using --decode
Verbosity:
--disptime <arg>print progress report every arg seconds
-S don't print progress report, VBR histograms
--nohist disable VBR histogram display
--silent don't print anything on screen
--quiet don't print anything on screen
--brief print more useful information
--verbose print a lot of useful information
Noise shaping & psycho acoustic algorithms:
-q <arg> <arg> = 0...9. Default -q 5
-q 0: Highest quality, very slow
-q 9: Poor quality, but fast
-h Same as -q 2. Recommended.
-f Same as -q 7. Fast, ok quality
CBR (constant bitrate, the default) options:
-b <bitrate> set the bitrate in kbps, default 128 kbps
--cbr enforce use of constant bitrate
ABR options:
--abr <bitrate> specify average bitrate desired (instead of quality)
VBR options:
-V n quality setting for VBR. default n=4
0=high quality,bigger files. 9=smaller files
-v the same as -V 4
--vbr-old use old variable bitrate (VBR) routine
--vbr-new use new variable bitrate (VBR) routine (default)
-b <bitrate> specify minimum allowed bitrate, default 32 kbps
-B <bitrate> specify maximum allowed bitrate, default 320 kbps
-F strictly enforce the -b option, for use with players that
do not support low bitrate mp3
-t disable writing LAME Tag
-T enable and force writing LAME Tag
PSY related:
--temporal-masking x x=0 disables, x=1 enables temporal masking effect
--nssafejoint M/S switching criterion
--nsmsfix <arg> M/S switching tuning [effective 0-3.5]
--interch x adjust inter-channel masking ratio
--ns-bass x adjust masking for sfbs 0 - 6 (long) 0 - 5 (short)
--ns-alto x adjust masking for sfbs 7 - 13 (long) 6 - 10 (short)
--ns-treble x adjust masking for sfbs 14 - 21 (long) 11 - 12 (short)
--ns-sfb21 x change ns-treble by x dB for sfb21
experimental switches:
-Y lets LAME ignore noise in sfb21, like in CBR
MP3 header/stream options:
-e <emp> de-emphasis n/5/c (obsolete)
-c mark as copyright
-o mark as non-original
-p error protection. adds 16 bit checksum to every frame
(the checksum is computed correctly)
--nores disable the bit reservoir
--strictly-enforce-ISO comply as much as possible to ISO MPEG spec
Filter options:
--lowpass <freq> frequency(kHz), lowpass filter cutoff above freq
--lowpass-width <freq> frequency(kHz) - default 15% of lowpass freq
--highpass <freq> frequency(kHz), highpass filter cutoff below freq
--highpass-width <freq> frequency(kHz) - default 15% of highpass freq
--resample <sfreq> sampling frequency of output file(kHz)- default=automatic
ID3 tag options:
--tt <title> audio/song title (max 30 chars for version 1 tag)
--ta <artist> audio/song artist (max 30 chars for version 1 tag)
--tl <album> audio/song album (max 30 chars for version 1 tag)
--ty <year> audio/song year of issue (1 to 9999)
--tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1)
--tn <track[/total]> audio/song track number and (optionally) the total
number of tracks on the original recording. (track
and total each 1 to 255. just the track number
creates v1.1 tag, providing a total forces v2.0).
--tg <genre> audio/song genre (name or number in list)
--ti <file> audio/song albumArt (jpeg/png/gif file, 128KB max, v2.3)
--tv <id=value> user-defined frame specified by id and value (v2.3 tag)
--add-id3v2 force addition of version 2 tag
--id3v1-only add only a version 1 tag
--id3v2-only add only a version 2 tag
--space-id3v1 pad version 1 tag with spaces instead of nulls
--pad-id3v2 same as '--pad-id3v2-size 128'
--pad-id3v2-size <value> adds version 2 tag, pad with extra <value> bytes
--genre-list print alphabetically sorted ID3 genre list and exit
--ignore-tag-errors ignore errors in values passed for tags
Note: A version 2 tag will NOT be added unless one of the input fields
won't fit in a version 1 tag (e.g. the title string is longer than 30
characters), or the '--add-id3v2' or '--id3v2-only' options are used,
or output is redirected to stdout.
MS-Windows-specific options:
--priority <type> sets the process priority:
0,1 = Low priority (IDLE_PRIORITY_CLASS)
2 = normal priority (NORMAL_PRIORITY_CLASS, default)
3,4 = High priority (HIGH_PRIORITY_CLASS))
Note: Calling '--priority' without a parameter will select priority 0.
Misc:
--license print License information
Platform specific:
--noasm <instructions> disable assembly optimizations for mmx/3dnow/sse
MPEG-1 layer III sample frequencies (kHz): 32 48 44.1
bitrates (kbps): 32 40 48 56 64 80 96 112 128 160 192 224 256 320
MPEG-2 layer III sample frequencies (kHz): 16 24 22.05
bitrates (kbps): 8 16 24 32 40 48 56 64 80 96 112 128 144 160
MPEG-2.5 layer III sample frequencies (kHz): 8 12 11.025
bitrates (kbps): 8 16 24 32 40 48 56 64

1
java/sound/txt/short Normal file
View File

@@ -0,0 +1 @@
medium.mp3

View File

@@ -0,0 +1,12 @@
junk (with or without header)
PCM_SIGNED 8000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian
-r 8k -t s16 -c 1 -e signed-integer
out (without header)
PCM_SIGNED 8000.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian
-r 128k -t s32 -c 2 -2 signed integer [reasonable]
out (without header)
PCM_SIGNED 192000.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
-r 192k -t s16 -c 2 [-e signed-integer]

BIN
java/sound/wget.exe Normal file

Binary file not shown.

BIN
java/sound/zlib1.dll Normal file

Binary file not shown.