Skip to content

Commit f64f5ad

Browse files
committed
wip
1 parent a5820b4 commit f64f5ad

8 files changed

Lines changed: 51 additions & 92 deletions

File tree

app/src/main/java/org/akanework/gramophone/logic/utils/exoplayer/NativeTrackAudioOutput.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import androidx.media3.exoplayer.analytics.PlayerId;
4444
import androidx.media3.exoplayer.audio.AudioOutput;
4545
import androidx.media3.exoplayer.audio.AudioOutputProvider.OutputConfig;
46-
import androidx.media3.exoplayer.audio.DefaultAudioSink;
46+
import androidx.media3.extractor.ExtractorUtil;
4747

4848
import org.nift4.gramophone.hificore.NativeTrack;
4949

@@ -234,7 +234,7 @@ public boolean write(ByteBuffer buffer, int encodedAccessUnitCount, long present
234234
throws WriteException {
235235
if (!isOutputPcm && framesPerEncodedSample == 0) {
236236
// If this is the first encoded sample, calculate the sample size in frames.
237-
framesPerEncodedSample = DefaultAudioSink.getFramesPerEncodedSample(config.encoding, buffer);
237+
framesPerEncodedSample = ExtractorUtil.getFramesPerEncodedSample(config.encoding, buffer);
238238
}
239239
maybeReportUnderrun();
240240
int bytesRemaining = buffer.remaining();

hificore/src/main/cpp/libusb/usb_device.c

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -376,69 +376,6 @@ Java_com_jwoolston_libusb_UsbDevice_nativeSetConfiguration(JNIEnv *env, jobject
376376
return libusb_set_configuration(deviceHandle, configurationID);
377377
}
378378

379-
JNIEXPORT jint JNICALL
380-
Java_com_jwoolston_libusb_UsbDevice_nativeControlRequest(JNIEnv *env, jobject instance,
381-
jlong device, jint requestType,
382-
jint request, jint value, jint index,
383-
jbyteArray buffer_, jint offset, jint length,
384-
jint timeout) {
385-
struct libusb_device_handle *deviceHandle = (struct libusb_device_handle *) device;
386-
jbyte *buffer = NULL;
387-
if (buffer_) {
388-
// We have to use this over GetPrimitiveArrayCritical due to the need to call other JNI functions
389-
buffer = (*env)->GetByteArrayElements(env, buffer_, NULL);
390-
}
391-
jint result = libusb_control_transfer(deviceHandle, (uint8_t) (0xFF & requestType), (uint8_t) (0xFF & request),
392-
(uint16_t) (0xFFFF & value), (uint16_t) (0xFFFF & index),
393-
(unsigned char *) (buffer + offset), (uint16_t) (0xFFFF & length),
394-
(unsigned int) timeout);
395-
if (buffer) {
396-
(*env)->ReleaseByteArrayElements(env, buffer_, buffer, 0);
397-
}
398-
399-
return result;
400-
}
401-
402-
JNIEXPORT jint JNICALL
403-
Java_com_jwoolston_libusb_UsbDevice_nativeBulkRequest(JNIEnv *env, jobject instance, jlong device,
404-
jint endpoint, jbyteArray buffer_, jint offset,
405-
jint length, jint timeout) {
406-
struct libusb_device_handle *deviceHandle = (struct libusb_device_handle *) device;
407-
jbyte *buffer = NULL;
408-
if (buffer_) {
409-
// We have to use this over GetPrimitiveArrayCritical due to the need to call other JNI functions
410-
buffer = (*env)->GetByteArrayElements(env, buffer_, NULL);
411-
}
412-
413-
int transferred;
414-
jint result = libusb_bulk_transfer(deviceHandle, (unsigned char) (0xFF & endpoint),
415-
(unsigned char*)buffer + offset, length, &transferred, (unsigned int) timeout);
416-
417-
if (buffer) {
418-
(*env)->ReleaseByteArrayElements(env, buffer_, buffer, 0);
419-
}
420-
return ((result == 0) ? transferred : result);
421-
}
422-
423-
JNIEXPORT jint JNICALL
424-
Java_com_jwoolston_libusb_UsbDevice_nativeInterruptRequest(JNIEnv *env, jobject instance,
425-
jlong device, jint endpoint,
426-
jbyteArray buffer_, jint offset,
427-
jint length, jint timeout) {
428-
struct libusb_device_handle *deviceHandle = (struct libusb_device_handle *) device;
429-
jbyte *buffer = NULL;
430-
if (buffer_) {
431-
// We have to use this over GetPrimitiveArrayCritical due to the need to call other JNI functions
432-
buffer = (*env)->GetByteArrayElements(env, buffer_, NULL);
433-
}
434-
jint transfered;
435-
jint result = libusb_interrupt_transfer(deviceHandle, endpoint, buffer + offset, length, &transfered, timeout);
436-
if (buffer) {
437-
(*env)->ReleaseByteArrayElements(env, buffer_, buffer, 0);
438-
}
439-
return ((result == 0) ? transfered : result);
440-
}
441-
442379
JNIEXPORT jint JNICALL
443380
Java_com_jwoolston_libusb_UsbDevice_nativeRequestAsync(JNIEnv *env, jobject instance,
444381
jlong device, jobject transfer,

hificore/src/main/java/com/jwoolston/libusb/AsyncUSBThread.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package com.jwoolston.libusb;
1818

19-
import androidx.media3.common.util.Log;
20-
2119
import org.jetbrains.annotations.NotNull;
2220

2321
/**

hificore/src/main/java/com/jwoolston/libusb/LibUsbDeviceDescriptor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
/**
2424
* @author Jared Woolston (Jared.Woolston@gmail.com)
2525
*/
26-
public class LibUsbDeviceDescriptor {
26+
class LibUsbDeviceDescriptor {
2727

2828
private final long nativeObject;
2929

hificore/src/main/java/com/jwoolston/libusb/UsbDevice.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
*/
4242
public class UsbDevice {
4343

44-
private final UsbManager manager;
44+
public final UsbManager manager;
4545
final @NotNull String name;
4646
final @Nullable String manufacturerName;
4747
final @Nullable String productName;
@@ -717,8 +717,9 @@ public int controlTransfer(int requestType, int request, int value, int index, b
717717
public int controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int offset,
718718
int length, int timeout) {
719719
checkBounds(buffer, offset, length);
720-
return nativeControlRequest(getNativeObject(), requestType, request, value, index, buffer, offset,
721-
length, timeout);
720+
// TODO: safely reimplement blocking transfer based on async transfer, in a real-time safe
721+
// way. most likely blocking on condition variable in native and setting it from callback.
722+
throw new UnsupportedOperationException();
722723
}
723724

724725
/**
@@ -755,7 +756,9 @@ public int bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int tim
755756
*/
756757
public int bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int offset, int length, int timeout) {
757758
checkBounds(buffer, offset, length);
758-
return nativeBulkRequest(getNativeObject(), endpoint.getAddress(), buffer, offset, length, timeout);
759+
// TODO: safely reimplement blocking transfer based on async transfer, in a real-time safe
760+
// way. most likely blocking on condition variable in native and setting it from callback.
761+
throw new UnsupportedOperationException();
759762
}
760763

761764
/**
@@ -792,7 +795,9 @@ public int interruptTransfer(UsbEndpoint endpoint, byte[] buffer, int length, in
792795
*/
793796
public int interruptTransfer(UsbEndpoint endpoint, byte[] buffer, int offset, int length, int timeout) {
794797
checkBounds(buffer, offset, length);
795-
return nativeInterruptRequest(getNativeObject(), endpoint.getAddress(), buffer, offset, length, timeout);
798+
// TODO: safely reimplement blocking transfer based on async transfer, in a real-time safe
799+
// way. most likely blocking on condition variable in native and setting it from callback.
800+
throw new UnsupportedOperationException();
796801
}
797802

798803
/**
@@ -822,6 +827,9 @@ public LibusbError asyncTransfer(@NotNull AsyncTransfer transfer) {
822827
throw new IllegalArgumentException("Transfer callback should be set");
823828
}
824829
@NonNull ByteBuffer buffer = transfer.getBuffer();
830+
manager.onTransferAdded(transfer.getNativeObject());
831+
// TODO: add dispatch to handler in real-time-safe way (if no dispatch and not blocking, it
832+
// may use real-time-unsafe in place callback)
825833
return LibusbError.fromNative(nativeRequestAsync(getNativeObject(), transfer,
826834
buffer, buffer.position(), buffer.remaining()));
827835
}
@@ -872,20 +880,11 @@ private static void checkBounds(byte[] buffer, int start, int length) {
872880

873881
private native int nativeSetConfiguration(long device, int configurationID);
874882

875-
private native int nativeControlRequest(long device, int requestType, int request, int value,
876-
int index, byte[] buffer, int offset, int length, int timeout);
877-
878883
private native int nativeRequestAsync(long device, @NotNull AsyncTransfer transfer,
879884
@NotNull ByteBuffer buffer, int offset, int length);
880885

881886
private native int nativeCancelAsync(long transfer);
882887

883-
private native int nativeBulkRequest(long device, int endpoint, byte[] buffer, int offset,
884-
int length, int timeout);
885-
886-
private native int nativeInterruptRequest(long device, int endpoint, byte[] buffer, int offset,
887-
int length, int timeout);
888-
889888
private native int nativeResetDevice(long device);
890889

891890
}

hificore/src/main/java/com/jwoolston/libusb/UsbManager.java

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
import org.jetbrains.annotations.NotNull;
2626
import org.nift4.gramophone.hificore.AdaptiveDynamicRangeCompression;
2727

28+
import java.util.HashSet;
29+
import java.util.Set;
30+
2831
/**
2932
* This class allows you to access the state of USB and communicate with USB devices.
3033
* Currently only host mode is supported in the public API.
@@ -46,6 +49,8 @@ public class UsbManager {
4649
private int refCount;
4750
@GuardedBy("#lock")
4851
private long nativeObject;
52+
@GuardedBy("#transfers")
53+
private final Set<Long> transfers = new HashSet<>();
4954

5055
final Object lock = new Object();
5156
private volatile AsyncUSBThread asyncUsbThread;
@@ -90,13 +95,20 @@ public void setNativeLogLevel(@NotNull LoggingLevel level) {
9095
}
9196

9297
public void destroy() {
98+
// both of these throw clauses shouldn't be reachable from finalizer. if everything is
99+
// leaked, GC will close it in the right order at least :)
93100
synchronized (lock) {
94101
if (refCount != 0) {
95-
throw new IllegalStateException("Can't close UsbManager if some device is still open!");
102+
throw new IllegalStateException("Can't destroy UsbManager if some device is still open!");
96103
}
97-
if (nativeObject != 0) {
98-
nativeDestroy(getNativeObject());
99-
nativeObject = 0;
104+
synchronized (transfers) {
105+
if (!transfers.isEmpty()) {
106+
throw new IllegalStateException("Can't destroy UsbManager if some transfer is still not released!");
107+
}
108+
if (nativeObject != 0) {
109+
nativeDestroy(nativeObject);
110+
nativeObject = 0;
111+
}
100112
}
101113
}
102114
}
@@ -107,13 +119,12 @@ protected void finalize() throws Throwable {
107119
super.finalize();
108120
}
109121

122+
@GuardedBy("#lock") // except AsyncUSBThread :)
110123
public long getNativeObject() {
111-
synchronized (lock) {
112-
if (nativeObject == 0) {
113-
throw new IllegalStateException("This UsbManager was already destroyed");
114-
}
115-
return nativeObject;
124+
if (nativeObject == 0) {
125+
throw new IllegalStateException("This UsbManager was already destroyed");
116126
}
127+
return nativeObject;
117128
}
118129

119130
@GuardedBy("#lock")
@@ -145,6 +156,19 @@ void startAsyncIfNeeded() {
145156
}
146157
}
147158

159+
void onTransferAdded(long transfer) {
160+
synchronized (transfers) {
161+
transfers.add(transfer);
162+
}
163+
}
164+
165+
// Do NOT call this manually, AsyncTransfer will call it.
166+
public void onTransferReleased(long transfer) {
167+
synchronized (transfers) {
168+
transfers.remove(transfer);
169+
}
170+
}
171+
148172
public enum LoggingLevel {
149173
NONE,
150174
ERROR,

hificore/src/main/java/com/jwoolston/libusb/async/AsyncTransfer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ public void release() {
395395
if (isInFlight())
396396
throw new IllegalStateException("Can't release in-progress transfer");
397397
nativeDestroy(getNativeObject());
398+
device.manager.onTransferReleased(nativeObject);
398399
nativeObject = 0;
399400
}
400401

media3

Submodule media3 updated 228 files

0 commit comments

Comments
 (0)