I have an mp3 file hello.mp3. I am wrapping the mp3 into FileInputStream and converting the input stream to bytes, then pushing the bytes to SynthesisCallback.audioAvailable(bytes,offset,length) but this results to just noise.The file hello.mp3 plays just fine if I load it to my Android Music play.
Why is this not working when I push bytes from the file to SnthesisCallback? I have pasted my code below.
This is where I generate the Audio stream from mp3 file:
class AudioStream {
InputStream stream;
int length;
}
private AudioStream getAudioStream(String text) throws IOException {
// TODO parse text, and generate audio file.
File hello = new File(Environment.getExternalStorageDirectory(), "hello.mp3");
AudioStream astream = new AudioStream();
astream.length = hello.length();
astream.stream = new FileInputStream(hello);
return astream;
}
This is my Inputstream to byte[] method.
public byte[] inputStreamToByteArray(AudioStream inStream) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[inStream.length];
int bytesRead;
while ((bytesRead = inStream.stream.read(buffer)) > 0) {
baos.write(buffer, 0, bytesRead);
}
return baos.toByteArray();
}
This is my onSynthesizeText method in my TextToSpeechService class.
#Override
protected synchronized void onSynthesizeText(SynthesisRequest request,
SynthesisCallback callback) {
// TODO load language and other checks.
// At this point, we have loaded the language
callback.start(16000,
AudioFormat.ENCODING_PCM_16BIT, 1 /* Number of channels. */);
final String text = request.getText().toLowerCase();
try {
Log.i(TAG, "Getting audio stream for text "+text);
AudioStream aStream = getAudioStream(text);
byte[] bytes = inputStreamToByteArray(aStream);
final int maxBufferSize = callback.getMaxBufferSize();
int offset = 0;
while (offset < aStream.length) {
int bytesToWrite = Math.min(maxBufferSize, aStream.length - offset);
callback.audioAvailable(bytes, offset, bytesToWrite);
offset += bytesToWrite;
}
} catch (Exception e) {
e.printStackTrace();
callback.error();
}
// Alright, we're done with our synthesis - yay!
callback.done();
}
This is how I am testing my synthesis-engine-in the making.
//initialize text speech
textToSpeech = new TextToSpeech(this, new OnInitListener() {
/**
* a callback to be invoked indicating the completion of the TextToSpeech
* engine initialization.
*/
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = textToSpeech.setLanguage(Locale.US);
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("error", "Language is not supported");
} else {
convertToSpeech("Hello");
}
} else {
Log.e("error", "Failed to Initilize!");
}
}
/**
* Speaks the string using the specified queuing strategy and speech parameters.
*/
private void convertToSpeech(String text) {
if (null == text || "".equals(text)) {
return;
}
textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
});
The function audioAvailable(byte[] buffer, int offset, int length) expects PCM samples as input. You cannot read bytes from .mp3 file and use it as input to the function. You need to use .wav file or first convert .mp3 file to .wav file and use it as input to audioAvailable function.
Related
I am using this Java Code for restoring android room database from SD card and it is works:
// Java
public static boolean copyToDirFromMultiFile(File dstDir, boolean
createDirsIfNotExist, File... srcFile) throws IOException {
if (createDirsIfNotExist && !dstDir.exists()) {
if (!dstDir.mkdirs()) return false;
}
for (File src : srcFile) {
File dstFile = new File(dstDir, src.getName());
try (InputStream inputStream = new FileInputStream(src); OutputStream outputStream = new FileOutputStream(dstFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
}
}
return true;
}
And when I tried to implement it with following code of Kotlin
// Kotlin
private fun copyToDirFromMultiFile(dstDir: String, originDir: String, fileName: Array<String>) {
fileName.forEach {
File(originDir).resolve(it).copyTo(File(dstDir).resolve(it), true)
}
}
Database file has copied but I have to restart my app, please tell me something I'm missed, Thank you very much.
Here is document I have found:
copyTo
My Mediarecorder gives me a PCM File as an output when I record the phone's microphone. Now when trying to listen to this File that it created all I hear is static and I think, if I have understood correctly, I get a PCM file from Mediarecorder not AAC and I need to add ADTS header to the PCM to be able to listen to it.
I have seen threads with custom Encoders but I can not seem to figure out where and what I need to do with them.
I make an output File from microphone recoridng like this:
private static final int CHANNEL = AudioFormat.CHANNEL_IN_MONO;
private static final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private static final int SAMPLE_RATE = 44100; //44.1kHz
private static final int BUFFER_SIZE = 2048;
public Status status = Status.IDLE;
private AudioRecordingHandler arh;
private File outputFile;
private Context context;
/**
* Starts script for running. Needs output file to work!
*/
public void start() {
if (outputFile == null) { return; }
System.out.println("Start reading stream...");
aacEncoder = new AACEncoder(SAMPLE_RATE, micOutputPCM);
new Thread(new Runnable() {
#Override
public void run() {
record.startRecording();
byte[] data = new byte[BUFFER_SIZE];
float[] audioFloatBuffer = new float[BUFFER_SIZE/2];
Yin y = new Yin(SAMPLE_RATE, BUFFER_SIZE/2);
while(status == Status.RECORDING) {
record.read(data, 0, BUFFER_SIZE);
audioFloatBuffer = ConverterUtil.toFloatArray(data, 0, audioFloatBuffer,
0, audioFloatBuffer.length);
PitchDetectionResult pdr = y.getPitch(audioFloatBuffer);
aacEncoder.writeIntoOutputfile(data);
arh.handlePitch(pdr.getPitch());
}
aacEncoder.stopEncoding();
}
}).start();
}
/**
* Stops script
*/
public void stop() {
status = Status.IDLE;
record.stop();
arh.finishedRecording(micOutputPCM);
}
Here is how I get the byte[] from the File and where I try to encode the ADTS header to them.
public static File addHeaderToAac(File micOutputPCM, File output) throws IOException {
byte[] pcmFile = fullyReadFileToBytes(micOutputPCM);
int bufferSize = 2048;
//addADTSHeader to byte[] and return a File object
return fileWithADTSHeader;
}
public static byte[] fullyReadFileToBytes(File f) throws IOException {
int size = (int) f.length();
byte bytes[] = new byte[size];
byte tmpBuff[] = new byte[size];
FileInputStream fis= new FileInputStream(f);;
try {
int read = fis.read(bytes, 0, size);
if (read < size) {
int remain = size - read;
while (remain > 0) {
read = fis.read(tmpBuff, 0, remain);
System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
remain -= read;
}
}
} catch (IOException e){
throw e;
} finally {
fis.close();
}
return bytes;
}
My question is, does anyone have an Encoder that can accept a File or byte[] or ByteStream as an input and return a File.
Because ultimately I want to make a mp4parser AACTrackImpl, which can be found here : https://github.com/sannies/mp4parser
AACTrackImpl aacTrack2 = new MP3TrackImpl(new FileDataSourceImpl(micOutputPCM));
Also If I am missing some important details about how to convert and what I should do to be able to play it then that information will also be useful.
If I need provide more information in order to answer this question, then I will gladly do so.
Edit:
I've been trying to make an encoder that would do what I need, but so far I have had no success.
public static File addHeaderToAac(File pcmFile1, File output, Context context) throws IOException {
byte[] pcmFile = fullyReadFileToBytes(pcmFile1);
int bufferSize = 2048;
AACEncoder encoder = new AACEncoder(44100, output);
encoder.encodeAudioFrameToAAC(pcmFile);
return output;
}
I am trying to encode the PCM to AAC with this encoder, but this encoder writes the output file to memory, but I need an object. And when I give it my byte[] it also gives me an error :
W/System.err: at java.nio.ByteBuffer.put(ByteBuffer.java:642)
And the error is coming from this line :
inputBuf.put(frameData);
Finally, my encoder:
public class AACEncoder {
final String TAG = "UEncoder Processor";
final int sampleRate;
File outputFile;
FileOutputStream fos;
final int TIMEOUT_USEC = 10000 ;
MediaCodec encoder;
boolean isEncoderRunning = false;
boolean outputDone = false;
MediaCodec.BufferInfo info;
public AACEncoder(final int sampleRate, File outputFile) {
this.sampleRate = sampleRate;
this.info = new MediaCodec.BufferInfo();
this.outputFile = outputFile;
openFileStream();
initEncoder();
}
/**
* Initializes CrappyEncoder for AAC-LC (Low complexity)
* #throws Exception
*/
public void initEncoder() {
try {
encoder = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
} catch (IOException ex) {
Log.e(TAG, "Failed to create CrappyEncoder");
ex.printStackTrace();
}
}
int generateIndex = 0;
public void encodeAudioFrameToAAC(byte[] frameData) {
if (encoder == null) return;
if (!isEncoderRunning) {
encoder.start();
isEncoderRunning = true;
}
ByteBuffer[] encoderInputBuffers = encoder.getInputBuffers();
if (fos != null) {
int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
if (inputBufIndex >= 0) {
long ptsUsec = (System.currentTimeMillis() * 1000) / 10000;
if (outputDone) {
encoder.queueInputBuffer(inputBufIndex, 0, 0, ptsUsec,
MediaCodec.BUFFER_FLAG_END_OF_STREAM);
} else {
ByteBuffer inputBuf = encoderInputBuffers[inputBufIndex];
inputBuf.clear();
inputBuf.put(frameData);
encoder.queueInputBuffer(inputBufIndex, 0, frameData.length, ptsUsec, 0);
}
generateIndex++;
}
tryEncodeOutputBuffer();
}
checkIfOutputDone();
}
/**
* Gets data from output buffer and encodes it to
* AAC-LC encoding with ADTS header attached before every frame
*/
private void tryEncodeOutputBuffer() {
ByteBuffer[] encoderOutputBuffers = encoder.getOutputBuffers();
//If >= 0 then valid response
int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
if (encoderStatus >= 0) {
ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];
encodedData.position(info.offset);
encodedData.limit(info.offset + info.size + 7);
byte[] data = new byte[info.size + 7];
addADTStoPacket(data, info.size + 7);
encodedData.get(data, 7, info.size);
encodedData.position(info.offset);
writeIntoOutputfile(data);
encoder.releaseOutputBuffer(encoderStatus, false);
}
}
private void checkIfOutputDone() {
if (outputDone) {
if (fos != null) {
try {
fos.close();
} catch (IOException ioe) {
Log.w(TAG, "failed closing debug file");
throw new RuntimeException(ioe);
}
fos = null;
}
}
}
/**
* Add ADTS header at the beginning of each and every AAC packet.
* This is needed as MediaCodec CrappyEncoder generates a packet of raw
* AAC data.
*
* Note the packetLen must count in the ADTS header itself.
**/
private void addADTStoPacket(byte[] packet, int packetLen) {
int profile = 2; //AAC LC
//39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;
int freqIdx = 4; //44.1KHz
int chanCfg = 2; //CPE
// fill in ADTS data
packet[0] = (byte)0xFF;
packet[1] = (byte)0xF9;
packet[2] = (byte)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
packet[3] = (byte)(((chanCfg&3)<<6) + (packetLen>>11));
packet[4] = (byte)((packetLen&0x7FF) >> 3);
packet[5] = (byte)(((packetLen&7)<<5) + 0x1F);
packet[6] = (byte)0xFC;
}
private void openFileStream() {
fos = null;
try {
fos = new FileOutputStream(outputFile, false);
} catch (FileNotFoundException e) {
Log.e("AudioRecorder", e.getMessage());
}
}
/**
* Writes data into file
* #param data
*/
public void writeIntoOutputfile(byte[] data) {
try {
fos.write(data);
} catch (IOException ioe) {
Log.w(TAG, "failed writing debug data to file");
throw new RuntimeException(ioe);
}
}
public void stopEncoding() {
isEncoderRunning = false;
encoder.stop();
closeStream();
}
private void closeStream() {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
Log.e("AudioRecorder", e.getMessage());
}
}
}
I have an app in which I have to read a .txt file so that I can store some values and keep them. This is working pretty well, except for the fact that I want to make those values non-readable or "non-understandable" for external users.
My idea was to convert the file content into Hex or Binary and, in the reading process, change it back to Char. The thing is that I don't have access to methods such as String.Format due to my compiler.
Here's how I'm currently reading and keeping the values:
byte[] buffer = new byte[1024];
int len = myFile.read(buffer);
String data = null;
int i=0;
data = new String(buffer,0,len);
Class to open and manipulate the file:
public class File {
private boolean debug = false;
private FileConnection fc = null;
private OutputStream os = null;
private InputStream is = null;
private String fileName = "example.txt";
private String pathName = "logs/";
final String rootName = "file:///a:/";
public File(String fileName, String pathName) {
super();
this.fileName = fileName;
this.pathName = pathName;
if (!pathName.endsWith("/")) {
this.pathName += "/"; // add a slash
}
}
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public void write(String text) throws IOException {
write(text.getBytes());
}
public void write(byte[] bytes) throws IOException {
if (debug)
System.out.println(new String(bytes));
os.write(bytes);
}
private FileConnection getFileConnection() throws IOException {
// check if subfolder exists
fc = (FileConnection) Connector.open(rootName + pathName);
if (!fc.exists() || !fc.isDirectory()) {
fc.mkdir();
if (debug)
System.out.println("Dir created");
}
// open file
fc = (FileConnection) Connector.open(rootName + pathName + fileName);
if (!fc.exists())
fc.create();
return fc;
}
/**
* release resources
*/
public void close() {
if (is != null)
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
is = null;
if (os != null)
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
os = null;
if (fc != null)
try {
fc.close();
} catch (IOException e) {
e.printStackTrace();
}
fc = null;
}
public void open(boolean writeAppend) throws IOException {
fc = getFileConnection();
if (!writeAppend)
fc.truncate(0);
is = fc.openInputStream();
os = fc.openOutputStream(fc.fileSize());
}
public int read(byte[] buffer) throws IOException {
return is.read(buffer);
}
public void delete() throws IOException {
close();
fc = (FileConnection) Connector.open(rootName + pathName + fileName);
if (fc.exists())
fc.delete();
}
}
I would like to know a simple way on how to read this content. Binary or Hex, both would work for me.
So, with some understanding of the question, I believe you're really looking for a form of obfuscation? As mentioned in the comments, the easiest way to do this is likely a form of cipher.
Consider this example implementation of a shift cipher:
Common
int shift = 11;
Writing
// Get the data to be wrote to file.
String data = ...
// cipher the data.
char[] chars = data.toCharArray();
for (int i = 0; i < chars.length; ++i) {
chars[i] = (char)(chars[i] + shift);
}
String cipher = new String(chars);
// Write the data to the cipher file.
...
Reading
// Read the cipher file.
String data = ...
// Decipher the data.
char[] chars = data.toCharArray();
for (int i = 0; i < chars.length; ++i) {
chars[i] = (char)(chars[i] - shift);
}
String decipher = new String(chars);
// Use data as required.
...
Here's an example implementation on Ideone. The output:
Data : I can read this IP 192.168.0.1
Cipher : T+nly+}plo+st~+T[+<D=9<AC9;9<
Decipher: I can read this IP 192.168.0.1
I tried to keep this as low level as possible in order to satisfy the Java 3 requirement.
Note that this is NOT secure by any means. Shift ciphers (like most ciphers in a bubble) are trivial to break by malicious entities. Please do not use this if security is an actual concern.
Your solution is too complex. With java 8, you can try :
String fileName = "configFile.txt";
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
//TO-DO .Ex
stream.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
My Delphi XE7 project needs to communicate with the FTDI FT311 Android Accessory Chip. They helpfully provide an Android demo that includes their JAVA driver FT311I2CInterface.java(shown later in this post). Presuming that I needed to convert this file to OP I followed the instructions for using the Java2OP.exe command line tool making the necessary path addition to point to the JDK (which seems to get installed by XE7) SET PATH=%PATH%;C:\Program Files\Java\jdk1.7.0_25\bin
With everything in the same folder I ran the tool with:
java2op.exe -unit FT311I2CInterface.java
received no errors and obtained an output file FT311I2CInterface.java.pas. However this output file has an empty class in it as follows:
{*******************************************************}
{ }
{ CodeGear Delphi Runtime Library }
{ Copyright(c) 2014 Embarcadero Technologies, Inc. }
{ }
{*******************************************************}
unit FT311I2CInterface.java;
interface
uses
Androidapi.JNIBridge;
type
// ===== Forward declarations =====
// ===== Interface declarations =====
implementation
procedure RegisterTypes;
begin
end;
initialization
RegisterTypes;
end.
Can anyone suggest what I am doing wrong please?
The original JAVA file as supplied is as follows:
//User must modify the below package with their package name
package com.I2CDemo;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
/******************************FT311 GPIO interface class******************************************/
public class FT311I2CInterface extends Activity
{
private static final String ACTION_USB_PERMISSION = "com.I2CDemo.USB_PERMISSION";
public UsbManager usbmanager;
public UsbAccessory usbaccessory;
public PendingIntent mPermissionIntent;
public ParcelFileDescriptor filedescriptor;
public FileInputStream inputstream;
public FileOutputStream outputstream;
public boolean mPermissionRequestPending = false;
public boolean READ_ENABLE = true;
public boolean accessory_attached = false;
public handler_thread handlerThread;
private byte [] usbdata;
private byte [] writeusbdata;
private int readcount;
private byte status;
private byte maxnumbytes = 60;
public boolean datareceived = false;
public Context global_context;
public static String ManufacturerString = "mManufacturer=FTDI";
public static String ModelString = "mModel=FTDII2CDemo";
public static String VersionString = "mVersion=1.0";
/*constructor*/
public FT311I2CInterface(Context context){
super();
global_context = context;
/*shall we start a thread here or what*/
usbdata = new byte[64];
writeusbdata = new byte[64];
/***********************USB handling******************************************/
usbmanager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
// Log.d("LED", "usbmanager" +usbmanager);
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
context.registerReceiver(mUsbReceiver, filter);
inputstream = null;
outputstream = null;
}
/*reset method*/
public void Reset()
{
/*create the packet*/
writeusbdata[0] = 0x34;
writeusbdata[1] = 0x00;
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
writeusbdata[4] = 0x00;
/*send the packet over the USB*/
SendPacket(5);
}
/*SetFrequency*/
public void SetFrequency(byte freq)
{
/*check for maximum and minimum freq*/
if(freq > 92)
freq = 92;
if (freq < 23)
freq = 23;
/*create the packet*/
writeusbdata[0] = 0x31;
switch(freq)
{
case 23:
writeusbdata[1] = 10;
break;
case 44:
writeusbdata[1] = 21;
break;
case 60:
writeusbdata[1] = 30;
break;
default:
writeusbdata[1] = 56;
break;
}
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
writeusbdata[4] = 0x00;
/*send the packet over the USB*/
SendPacket(5);
}
/*write data*/
public byte WriteData(byte i2cDeviceAddress,byte transferOptions,
byte numBytes, byte[] buffer,
byte [] actualNumBytes)
{
status = 0x01; /*error by default*/
/*
* if num bytes are more than maximum limit
*/
if(numBytes < 1){
actualNumBytes[0] = (byte)0x00;
/*return the status with the error in the command*/
return status;
}
/*check for maximum limit*/
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
/*prepare the packet to be sent*/
for(int count = 0;count<numBytes;count++)
{
writeusbdata[4+count] = (byte)buffer[count];
}
/*prepare the usbpacket*/
writeusbdata[0] = 0x32;
writeusbdata[1] = i2cDeviceAddress;
writeusbdata[2] = transferOptions;
writeusbdata[3] = numBytes;
SendPacket((int)(numBytes+4));
datareceived = false;
/*wait while the data is received*/
/*FIXME, may be create a thread to wait on , but any
* way has to wait in while loop
*/
while(true){
if(datareceived == true){
break;
}
}
/*by default it error*/
status = 0x01;
/*check for the received data*/
if(usbdata[0] == 0x32)
{
/*check for return error status*/
status = usbdata[1];
/*updated the written bytes*/
actualNumBytes[0] = usbdata[3];
}
datareceived = false;
return status;
}
/*read data*/
public byte ReadData(byte i2cDeviceAddress,byte transferOptions,
byte numBytes, byte[] readBuffer,
byte [] actualNumBytes)
{
status = 0x01; /*error by default*/
/*should be at least one byte to read*/
if(numBytes < 1){
return status;
}
/*check for max limit*/
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
/*prepare the packet to send this command*/
writeusbdata[0] = 0x33; /*read data command*/
writeusbdata[1] = i2cDeviceAddress; /*device address*/
writeusbdata[2] = transferOptions; /*transfer options*/
writeusbdata[3] = numBytes; /*number of bytes*/
/*send the data on USB bus*/
SendPacket(4);
datareceived = false;
/*wait for data to arrive*/
while(true)
{
if(datareceived == true){
break;
}
}
/*check the received data*/
if(usbdata[0] == 0x33)
{
/*check the return status*/
status = usbdata[1];
/*check the received data length*/
numBytes = usbdata[3];
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
for(int count = 0; count<numBytes;count++)
{
readBuffer[count] = usbdata[4+count];
}
/*update the actual number of bytes*/
actualNumBytes[0] = numBytes;
datareceived = false;
}
return status;
}
/*method to send on USB*/
private void SendPacket(int numBytes)
{
try {
if(outputstream != null){
outputstream.write(writeusbdata, 0,numBytes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*resume accessory*/
public void ResumeAccessory()
{
// Intent intent = getIntent();
if (inputstream != null && outputstream != null) {
return;
}
UsbAccessory[] accessories = usbmanager.getAccessoryList();
if(accessories != null)
{
Toast.makeText(global_context, "Accessory Attached", Toast.LENGTH_SHORT).show();
}
else
{
accessory_attached = false;
return;
}
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if( -1 == accessory.toString().indexOf(ManufacturerString))
{
Toast.makeText(global_context, "Manufacturer is not matched!", Toast.LENGTH_SHORT).show();
return;
}
if( -1 == accessory.toString().indexOf(ModelString))
{
Toast.makeText(global_context, "Model is not matched!", Toast.LENGTH_SHORT).show();
return;
}
if( -1 == accessory.toString().indexOf(VersionString))
{
Toast.makeText(global_context, "Version is not matched!", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(global_context, "Manufacturer, Model & Version are matched!", Toast.LENGTH_SHORT).show();
accessory_attached = true;
if (usbmanager.hasPermission(accessory)) {
OpenAccessory(accessory);
}
else
{
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
Toast.makeText(global_context, "Request USB Permission", Toast.LENGTH_SHORT).show();
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {}
}
/*destroy accessory*/
public void DestroyAccessory(){
global_context.unregisterReceiver(mUsbReceiver);
if(accessory_attached == true)
{
READ_ENABLE = false;
byte i2cDeviceAddress = 1;
byte transferOptions = bOption.START_BIT;
byte numBytes = 2;
byte [] actualNumBytes = new byte[1];
byte [] readBuffer = new byte[60];
//byte deviceAddress = 1;
readBuffer[0] = 1;
ReadData(i2cDeviceAddress,transferOptions,
numBytes, readBuffer,
actualNumBytes);
try{Thread.sleep(10);}
catch(Exception e){}
}
CloseAccessory();
}
/*********************helper routines*************************************************/
public void OpenAccessory(UsbAccessory accessory)
{
filedescriptor = usbmanager.openAccessory(accessory);
if(filedescriptor != null){
usbaccessory = accessory;
FileDescriptor fd = filedescriptor.getFileDescriptor();
inputstream = new FileInputStream(fd);
outputstream = new FileOutputStream(fd);
/*check if any of them are null*/
if(inputstream == null || outputstream==null){
return;
}
}
handlerThread = new handler_thread(inputstream);
handlerThread.start();
}
private void CloseAccessory()
{
try{
if(filedescriptor != null)
filedescriptor.close();
}catch (IOException e){}
try {
if(inputstream != null)
inputstream.close();
} catch(IOException e){}
try {
if(outputstream != null)
outputstream.close();
}catch(IOException e){}
/*FIXME, add the notfication also to close the application*/
filedescriptor = null;
inputstream = null;
outputstream = null;
System.exit(0);
}
/***********USB broadcast receiver*******************************************/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action))
{
synchronized (this)
{
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
{
Toast.makeText(global_context, "Allow USB Permission", Toast.LENGTH_SHORT).show();
OpenAccessory(accessory);
}
else
{
Toast.makeText(global_context, "Deny USB Permission", Toast.LENGTH_SHORT).show();
Log.d("LED", "permission denied for accessory "+ accessory);
}
mPermissionRequestPending = false;
}
}
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
CloseAccessory();
}else
{
Log.d("LED", "....");
}
}
};
/*usb input data handler*/
private class handler_thread extends Thread {
FileInputStream instream;
handler_thread(FileInputStream stream ){
instream = stream;
}
public void run()
{
while(READ_ENABLE == true)
{
try
{
/*dont overwrite the previous buffer*/
if((instream != null) && (datareceived==false))
{
readcount = instream.read(usbdata,0,64);
if(readcount > 0)
{
datareceived = true;
/*send only when you find something*/
}
}
}catch (IOException e){}
}
}
}
}
I am a beginner with Android and I am also trying to interface the FT311.
I will share my experience with Java2OP but I am not yet able to get the usbAccessory in Delphi XE7
UsbManager := TJUsbManager.Wrap(SharedActivityContext.getSystemService(TJContext.JavaClass.USB_SERVICE));
AccessoryList := UsbManager.getAccessoryList();
if ( AccessoryList <> nil ) then begin
if ( AccessoryList.Length > 0 ) then begin
Accessory := AccessoryList.Items[0]; <<<<<<< raise an illegal instruction , access violation..
end;
end;
I had many troubles to use java2op but Here are the steps I follow After googling (sorry I don't remember the urls)
create a .jar file with eclipse ADT containing the class you need (I use FT311GPIOInterface.java from the FT31 demo project supplyed by FTDI). It is not as easy because you have to split the demo app into a "android project library" (the one which will produce the .jar) and an "android project" the UI of the demo app. The .jar is build when you build and run the demo app (not when you build the android project library).
If you want to test your .jar with the UI app, you have to copy the .jar into the UI app in the directory Libs and then deploy it on the android device
I am new to eclipse, there is probably a better way to do it but ...
I saw other way to produce the .jar file
See brian long web site for another way to
Java2op : It works on a clean XP windows : I use a virtual machine, no delphi XE installed, with java jdk1.7.0_25, java2op installed, no android SDK.
my jar is ft311lib.jar
java2op -jar ft311lib.jar -unit com.poco.ft311lib
this produce com.poco.ft311lib.pas
Hope this help
According the linked documentation about this command line tool, I would do the following:
create a src/ folder and put FT311I2CInterface.java in it.
run java2op.exe with those args:
java2op.exe -source src/ -unit Android.JNI.FT311I2C
Expected output :
Android.JNI.FT311I2C.pas
The -unit arg specify the output.
The -source arg specify the input (in your case you need a java source file)
Java2OP.exe ... is a command-line tool that you
can use to generate Delphi native bridge files from Java libraries
(JAR or class files).
I suggest to check if you used the tool correctly:
java2op.exe -unit FT311I2CInterface.java
According to the documentation, -unit specifies File name of the output unit, not the input file. It also says
You must specify at least one input option that indicates what
content you want to include in the output Delphi native bridge file.
Try instead:
java2op.exe -source .
i am using this code to publish audio to red5 server and testing it via publisher demo to see if i am able to hear what i am publshing.
the packets are getting sent successully but unable to hear audio. please help me out i am not able to figure out the error.
package testx;
import com.xuggle.ferry.IBuffer;
import com.xuggle.xuggler.*;
import com.xuggle.xuggler.IAudioSamples.Format;
import javax.sound.sampled.*;
public class Testx{
private static IContainer outContainer;
private static IContainerFormat outContainerFormat;
private static IStreamCoder outAudioCoder;
private static IStream outAudioStream;
public static void main(String args[])
{
String urlOut ="rtmp://localhost:1935/oflaDemo/xxx";
outContainer = IContainer.make();
outContainerFormat = IContainerFormat.make();
outContainerFormat.setOutputFormat("flv", urlOut, null);
int retVal = outContainer.open(urlOut, IContainer.Type.WRITE, outContainerFormat);
if (retVal < 0) {
System.out.println("Could not open output container");
return;
}
outAudioStream = outContainer.addNewStream(1);
outAudioCoder = outAudioStream.getStreamCoder();
ICodec cdc = ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_AAC);
outAudioCoder.setCodec(cdc);
outAudioCoder.setSampleRate(44100);
outAudioCoder.setChannels(1);
outAudioCoder.setFrameRate(IRational.make(44100,1));
outAudioCoder.setSampleFormat(Format.FMT_S16);
outAudioCoder.setBitRate(64000);
retVal = outAudioCoder.open(null,null);
if (retVal < 0) {
System.out.println("Could not open audio coder");
return;
}
retVal = outContainer.writeHeader();
if (retVal < 0) {
System.out.println("Could not write output FLV header: ");
return ;
}
AudioFormat audioFormat = new AudioFormat(44100,
(int)16,
1,
true, /* xuggler defaults to signed 16 bit samples */
false);
TargetDataLine line = null;
DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
if (!AudioSystem.isLineSupported(info)) {
return;
}
// Obtain and open the line.
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(audioFormat);
} catch (LineUnavailableException ex) {
return;
}
// Begin audio capture.
line.start();
long lastPos_out=0;
long audtioTime =0;
long startTime = System.nanoTime();
while(1)
{
byte[] data = new byte[line.getBufferSize()/5];
int sz = line.read(data, 0, data.length);
if(sz>0)
{
long nanoTs = System.nanoTime()-startTime;
IBuffer iBuf = IBuffer.make(null,data,0,sz);
System.out.println(iBuf.toString());
IAudioSamples smp = IAudioSamples.make(iBuf, 1,IAudioSamples.Format.FMT_S16);
smp.setComplete(true,sz/2,44100,1,Format.FMT_S16, nanoTs / 1000);
int samplesConsumed = 0;
while(samplesConsumed<smp.getNumSamples()){
IPacket packet= IPacket.make();
samplesConsumed +=outAudioCoder.encodeAudio(packet, smp, samplesConsumed);
if (packet.isComplete()) {
// packet.setKeyPacket(true);
packet.setPosition(lastPos_out);
packet.setStreamIndex(1);
lastPos_out+=packet.getSize();
outContainer.writePacket(packet);
}
}
}
// try {
// Thread.sleep((long)10000);
//} catch (InterruptedException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
// }
}
}
}
Solved it, my microphone volume was very low and set the rate to 16khz