dagargo / overwitch

JACK client for Overbridge devices

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Buffer overflow on any Elektron device with >2 inputs

CarlColglazier opened this issue · comments

Overwitch does not throw an error with only two outputs, but it does lead to distortion as noted here: https://www.elektronauts.com/t/overwitch-a-jack-client-for-overbridge-devices-aka-overbridge-for-linux/153983/16

Using the correct number of outputs to match the Overbridge standalone, however, leads to a buffer overflow.

ERROR:overwitch.c:290:(overwitch_j2o): j2o: Buffer overflow. Discarding data...

It's interesting that the only device that fails because of this is the only one that has 4 inputs.
Probably, what's happening is that we are writing 4 tracks to the buffer but we are not reading the 4, which would lead to this scenario. But there could be other reasons too.

Could you run it again with overwitch -v -v?

I've replicated the same problem on the Analog Four MK2 (6 output channels) and the Analog RYTM MK2 (12 input channels).

Here's what I get from overwitch -v -v (on the A4 with 6 inputs):

DEBUG:overbridge.c:370:(overbridge_init_priv): Device: Analog Four MKII
/dev/shm/jack_db/__db.001: Permission denied
Cannot open DB environment: Permission denied
DEBUG:overwitch.c:101:(overwitch_sample_rate_cb): JACK sample rate: 48000
DEBUG:overbridge.c:480:(overbridge_run): Starting device...
DEBUG:overbridge.c:462:(run): Running device...
DEBUG:overwitch.c:129:(overwitch_buffer_size_cb): JACK buffer size: 64
DEBUG:overwitch.c:135:(overwitch_buffer_size_cb): Target delay: 5.500000 ms (264 frames)
DEBUG:overwitch.c:162:(overwitch_j2o_reader): j2o: Can not read data from queue
DEBUG:overwitch.c:357:(overwitch_compute_ratios): max. latencies (ms): 0.0, 0.0; avg. ratios: 1.000000, 1.000000
DEBUG:overwitch.c:372:(overwitch_compute_ratios): Retunning loop filter...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:201:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:291:(overwitch_j2o): j2o: Buffer overflow. Discarding data...

I have a few questions.

Do you see this every time?

DEBUG:overbridge.c:370:(overbridge_init_priv): Device: Analog Four MKII
/dev/shm/jack_db/__db.001: Permission denied
Cannot open DB environment: Permission denied
[...]

Are the buffer overflow random or did you do something to replicate the error? What did you do?
Before I announced the project I was having some random problems at startup that were causing the buffer overflow but I thought I had fixed these.

Is there any menu on the Analog Heat that allows you to choose the channels you want to stream over USB?

Do you get xruns in JACK? Is it possible that your computer is not powerful enough for the 2 additional tracks? If so, try to change the converters to something faster. See this.

overwitch/src/overwitch.c

Lines 567 to 572 in 38edbdb

j2o_state =
src_callback_new (overwitch_j2o_reader, SRC_SINC_FASTEST,
ob.device_desc.inputs, NULL, NULL);
o2j_state =
src_callback_new (overwitch_o2j_reader, SRC_SINC_FASTEST,
ob.device_desc.outputs, NULL, NULL);

Do you see this every time?

Yes, I'm pretty sure it also does that with the Digitone as well. Probably something on my end.

Are the buffer overflow random or did you do something to replicate the error? What did you do?

All that's needed is to set the outputs to >2. It's not overflowing every time. I had the program spit out the bytes <= wsj2o and it does sometimes work.

Is there any menu on the Analog Heat that allows you to choose the channels you want to stream over USB?

There is a basic routing page with the "analog in/out" options: auto, in+out, in, out, off. I think this lets you send audio to the Heat from both OB and the analog inputs.

Do you get xruns in JACK?

Nope, unless things get really out of hand. I'm running with a buffer size of 128 for these tests.

I suspect your problem is related to how the tunning (period of time it takes to self adjust before sending audio) is performed and might affect others, I have pushed a commit that I'm quite sure does thing better now. Could you try this?

We're talking about the inputs the device has, right? Or the outputs from the computer but let's stick to the definition of the C struct.

In this example the ARMK2 has 2 inputs and 12 outputs. Sorry if I'm being too pedantic.

static const struct overbridge_device_desc ARMK2_DESC = {
  .pid = ARMK2_PID,
  .name = "Analog Rytm MKII",
  .inputs = 2,
  .outputs = 12,
  .input_track_names = {"Output L", "Output R"},
  .output_track_names = {"Master L", "Master R", "BD", "SD", "RS-CP",
			 "BT", "LT", "MT-HT", "CH-OH", "CY-CB", "Input L",
			 "Input R"}
};

It's possible that Overwitch might interprete the data received (the 12 output tracks from the ARMK2) as fewer tracks than the ones the device is sending but it is not possible that Overwitch will send more tracks than the device is expecting without causing undesired problems.

To be clear: audio from the device to the computer works no problem. The issue is getting the audio from the computer to the device. The changing perspective of what's an input/output is confusing!

I suspect your problem is related to how the tunning (period of time it takes to self adjust before sending audio) is performed and might affect others, I have pushed a commit that I'm quite sure does thing better now. Could you try this?

Same as before unfortunately. Audio sounds bit-reduced with .inputs = 2 and the program buffer overflows with .inputs = 6.

We'll fix the bit reduction later as it has nothing to do -I hope- with the buffer overflow.

I know is very confusing, sorry. I came up with the better possible schema from my POV. I ended naming most of the variables with the suffixes o2j and j2o to make things as clear as possible. But notice that from the device, which is the overbridge.c file, o2j means that it is writing to JACK while from the computer, which is overwitch.c file, o2j means that it is reading. And then we have the complementary. 🤯

But, which device has 6 inputs?

But, which device has 6 inputs?

Analog Four MK2.

AFAIK, it has 6 outputs and 2 inputs, hasn't it?

Sorry, the Analog Four MK2 has 8 outputs and 6 inputs.

Just one more question. Could you post here the ratios you get when you run it in verbose mode and you're having the buffer overflow?

All that's needed is to set the outputs to >2. It's not overflowing every time. I had the program spit out the bytes <= wsj2o and it does sometimes work.

It sometimes works because the problem is that more data is being written in the circular buffer than it's being read. Since we are skipping that write at some point in the future there will be available space again.

On the Analog Heat MK2:

DEBUG:overwitch.c:382:(overwitch_compute_ratios): max. latencies (ms): 0.0, 0.0; avg. ratios: 1.000000, 1.000000
DEBUG:overwitch.c:382:(overwitch_compute_ratios): max. latencies (ms): 6.6, 21.3; avg. ratios: 1.000050, 0.999950
DEBUG:overwitch.c:382:(overwitch_compute_ratios): max. latencies (ms): 6.6, 21.3; avg. ratios: 1.000041, 0.999959
DEBUG:overwitch.c:382:(overwitch_compute_ratios): max. latencies (ms): 6.6, 21.3; avg. ratios: 1.000038, 0.999962
DEBUG:overwitch.c:382:(overwitch_compute_ratios): max. latencies (ms): 6.6, 21.3; avg. ratios: 1.000027, 0.999973
DEBUG:overwitch.c:382:(overwitch_compute_ratios): max. latencies (ms): 6.6, 21.3; avg. ratios: 1.000014, 0.999986

I have fixed a problem when calculating the first iteration and I've increased the tuning time to 5 s in 746946f.

I've fixed also a couple of bugs. f71dda2 might affect you too regarding the noisy audio.

But I'm not sure if these will solve your problems.

Did you manage to try those commits?

I've checked everything and I think everything should work with more than 2 inputs. Perhaps the problem was in the ratios you were getting initially so there was more data produced than consumed. Since this has been addressed, I think you should try.
This hypothesis is backed up by your output, because the ratios are clearly changing.

This is what happens now. It's much more stable.

$ overwitch -v
DEBUG:overbridge.c:361:(overbridge_init_priv): Device: Digitakt
DEBUG:overwitch.c:100:(overwitch_sample_rate_cb): JACK sample rate: 48000
DEBUG:overbridge.c:470:(overbridge_run): Starting device...
DEBUG:overwitch.c:128:(overwitch_buffer_size_cb): JACK buffer size: 64
DEBUG:overbridge.c:453:(run): Running device...
DEBUG:overwitch.c:392:(overwitch_compute_ratios): max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999872, 1.000128
DEBUG:overwitch.c:392:(overwitch_compute_ratios): max. latencies (ms): 5.3, 5.2; avg. ratios: 0.999916, 1.000084
DEBUG:overwitch.c:392:(overwitch_compute_ratios): max. latencies (ms): 5.3, 5.6; avg. ratios: 0.999882, 1.000118
DEBUG:overwitch.c:392:(overwitch_compute_ratios): max. latencies (ms): 5.4, 5.6; avg. ratios: 0.999887, 1.000113
DEBUG:overwitch.c:392:(overwitch_compute_ratios): max. latencies (ms): 5.4, 5.6; avg. ratios: 0.999884, 1.000116

Let's focus on the Analog Heat MK2 (4x4).

Let me know if that works for you.

I run Overwitch on a less powerful computer and I could replicate your issue when running it without chrt.
When running it with this, as suggested in the README.md now, no buffer overflow issues arise.

Gave this a go with CPU governance at performance.

chrt -f 35 overwitch -v

DEBUG:overbridge.c:371:(overbridge_init_priv): Device: Analog Heat MKII
DEBUG:overwitch.c:101:(overwitch_sample_rate_cb): JACK sample rate: 48000
DEBUG:overbridge.c:480:(overbridge_run): Starting device...
DEBUG:overwitch.c:129:(overwitch_buffer_size_cb): JACK buffer size: 64
DEBUG:overbridge.c:463:(run): Running device...
DEBUG:overwitch.c:386:(overwitch_compute_ratios): max. latencies (ms): 0.0, 0.0; avg. ratios: 1.000030, 0.999971
ERROR:overwitch.c:292:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:292:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:292:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:292:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
ERROR:overwitch.c:292:(overwitch_j2o): j2o: Buffer overflow. Discarding data...
 ...
^CDEBUG:overwitch.c:461:(overwitch_exit): Max. latencies (ms): 4.9, 21.2
DEBUG:overwitch.c:613:(overwitch_run): Exiting...

I'm sorry this is not working for you but without having a device with more than 2 inputs it's difficult to spot the issue.

I've made a few little changes. No one is addressing your issue but hopefully these will help to fix it.

Try to change this value to something higher. This value is measured in seconds and it's the time it takes to stabilize the ratios. Try with 60, for instance. It's a lot but this will show if the problem is in the ratios.

#define STARTUP_TIME 5

In case the problem is in the initial ratios, I have pushed a commit that should improve that.
But I'm not sure anymore if that's the problem.

I've added a quality option to set the resampling algorithm and I've removed the buffer size limitation on the JACK end also.

While I was checking out these, I have somehow replicated the error.

$ overwitch -q 0 -v
Device: Digitakt (outputs: 12, inputs: 2)
JACK sample rate: 48000
JACK buffer size: 64
DEBUG:overbridge.c:471:(overbridge_run): Starting device thread...
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.950151, 1.052474; curr. ratios: 0.950000, 1.052632
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.950000, 1.052632; curr. ratios: 0.950000, 1.052632
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.950000, 1.052632; curr. ratios: 0.950000, 1.052632
ERROR:overwitch.c:266:(overwitch_j2o): j2o: Buffer overflow. Discarding data...

But with a lower quality setting it works. Notice that 0 is the highest quality and most CPU expensive algorithm, while 4 is the lowest quality and least CPU expensive. If no value is provided, 2 is used.

$ overwitch -v
Device: Digitakt (outputs: 12, inputs: 2)
JACK sample rate: 48000
JACK buffer size: 64
DEBUG:overbridge.c:471:(overbridge_run): Starting device thread...
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999880, 1.000121; curr. ratios: 0.999922, 1.000078
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999969, 1.000031; curr. ratios: 0.999909, 1.000091
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999914, 1.000086; curr. ratios: 0.999888, 1.000112
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999871, 1.000129; curr. ratios: 0.999902, 1.000098
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999859, 1.000141; curr. ratios: 0.999876, 1.000124
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999868, 1.000132; curr. ratios: 0.999852, 1.000148
DEBUG:overwitch.c:361:(overwitch_compute_ratios): Max. latencies (ms): 5.4, 5.1; avg. ratios: 0.999879, 1.000121; curr. ratios: 0.999886, 1.000114

This means that Overwitch is sensitive to starting conditions and that one of this conditions is the algorithm quality. This makes sense too because you're using more tracks.

Try with a lower quality setting and let me know if this improves anything.

Also, on what computer (CPU) are you running this?

I'll try out the new code later today.

Here's some information on my CPU:

processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 60
model name      : Intel(R) Core(TM) i7-4810MQ CPU @ 2.80GHz
stepping        : 3
microcode       : 0x1c
cpu MHz         : 2775.097

I've just pushed ffaf7b5 which fixes the error on the highest quality setting I was getting. It just skips the first JACK cycle calculation.

The good news is the different audio quality settings do affect the DSP use. The bad news is that I'm still getting the same errors on my system (though after a delay). I may borrow a more powerful system in the near future and see how it handles things.

Testing the Analog Heat on another machine sounds like a good idea. I'll test it on different computers.

BTW, did you disable the Hyperthreading (dummy) cores? The README.md includes instructions for this.

But everything indicates that the error is in the code. I'll check it out again.

Applying these changes we can make the device to have 12 inputs. The remaining changes are needed in order to skip the undesired samples and to size the USB blocks properly. And everything works fine. 😕

$ git diff
diff --git a/src/overbridge.c b/src/overbridge.c
index 65adeaf..728e71e 100644
--- a/src/overbridge.c
+++ b/src/overbridge.c
@@ -47,9 +47,10 @@
 static const struct overbridge_device_desc DIGITAKT_DESC = {
   .pid = DTAKT_PID,
   .name = "Digitakt",
-  .inputs = 2,
+  .inputs = 12,
   .outputs = 12,
-  .input_track_names = {"Output L", "Output R"},
+  .input_track_names = {"Output L", "Output R", "q", "w", "e", "r",
+                       "t", "y", "u", "i", "o", "p"},
   .output_track_names =
     {"Master L", "Master R", "Track 1", "Track 2", "Track 3", "Track 4",
      "Track 5", "Track 6", "Track 7", "Track 8", "Input L", "Input R"}
@@ -264,13 +265,14 @@ set_usb_output_data_blks (struct overbridge *ob)
       s = blk->data;
       for (int j = 0; j < OB_FRAMES_PER_BLOCK; j++)
        {
-         for (int k = 0; k < ob->device_desc.inputs; k++)
+         for (int k = 0; k < 2; k++)
            {
              hv = htonl (*f * INT_MAX);
              *s = hv;
              f++;
              s++;
            }
+         f += 10;
        }
     }
 }
@@ -504,7 +506,7 @@ overbridge_init (struct overbridge *ob)
        sizeof (int32_t) * OB_FRAMES_PER_BLOCK * ob->device_desc.outputs;
       ob->usb_data_out_blk_len =
        sizeof (struct overbridge_usb_blk) +
-       sizeof (int32_t) * OB_FRAMES_PER_BLOCK * ob->device_desc.inputs;
+       sizeof (int32_t) * OB_FRAMES_PER_BLOCK * 2;
       int usb_data_in_len = ob->usb_data_in_blk_len * OB_BLOCKS_PER_TRANSFER;
       int usb_data_out_len =
        ob->usb_data_out_blk_len * OB_BLOCKS_PER_TRANSFER;
$ chrt -f 35 overwitch -v
Device: Digitakt (outputs: 12, inputs: 12)
JACK sample rate: 48000
JACK buffer size: 64
DEBUG:overbridge.c:473:(overbridge_run): Starting device thread...
DEBUG:overwitch.c:370:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999818, 1.000182; curr. ratios: 0.999773, 1.000227
DEBUG:overwitch.c:370:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999851, 1.000149; curr. ratios: 0.999901, 1.000099
DEBUG:overwitch.c:370:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999900, 1.000100; curr. ratios: 0.999948, 1.000052
DEBUG:overwitch.c:370:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999910, 1.000090; curr. ratios: 0.999918, 1.000082
DEBUG:overwitch.c:370:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999911, 1.000089; curr. ratios: 0.999878, 1.000122
DEBUG:overwitch.c:370:(overwitch_compute_ratios): Max. latencies (ms): 5.1, 5.2; avg. ratios: 0.999888, 1.000112; curr. ratios: 0.999888, 1.000112

Summarizing my previous comment, I don't think the problem is in the buffers not being copied properly from JACK to the device.

I've tested Overwitch on a really old laptop (Intel Core 2 Duo with a 32 bits OS) with the same interface the same device and an RT kernel and it just worked. The only problem is that I need a bigger buffer.

However, I've noticed that there was a bug in the code related to the 128 frames buffer size limitation so larger buffer sizes would lead to the same error you were getting. But this was only happening with 512 frames buffer size and bigger so not sure if this would fix anything in your case.

If you want to try this, please post the output of chrt -f 35 overwitch -v -v.

Here's what I'm getting.

chrt -f 35 overwitch -v -v
DEBUG:overbridge.c:362:(overbridge_init_priv): Checking for Digitakt...
DEBUG:overbridge.c:362:(overbridge_init_priv): Checking for Digitone...
DEBUG:overbridge.c:362:(overbridge_init_priv): Checking for Analog Four MKII...
DEBUG:overbridge.c:362:(overbridge_init_priv): Checking for Analog Rytm MKII...
DEBUG:overbridge.c:362:(overbridge_init_priv): Checking for Analog Heat MKII...
Device: Analog Heat MKII (outputs: 4, inputs: 4)
JACK sample rate: 48000
JACK buffer size: 128
DEBUG:overwitch.c:111:(overwitch_init_buffer_size): Target delay: 7.5 ms (360 frames)
DEBUG:overbridge.c:483:(overbridge_run): Starting device thread...
DEBUG:overwitch.c:136:(overwitch_j2o_reader): j2o: Can not read data from queue
DEBUG:overwitch.c:331:(overwitch_compute_ratios): Starting up...
DEBUG:overwitch.c:364:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 0.999917, 1.000083; curr. ratios: 1.000180, 0.999820
DEBUG:overwitch.c:378:(overwitch_compute_ratios): Tunning...
DEBUG:overwitch.c:364:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 1.000060, 0.999940; curr. ratios: 1.000020, 0.999980
DEBUG:overwitch.c:364:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 1.000016, 0.999984; curr. ratios: 1.000010, 0.999990
DEBUG:overwitch.c:364:(overwitch_compute_ratios): Max. latencies (ms): 0.0, 0.0; avg. ratios: 1.000011, 0.999989; curr. ratios: 1.000011, 0.999989
DEBUG:overwitch.c:391:(overwitch_compute_ratios): Running...
DEBUG:overwitch.c:175:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:175:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:175:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:175:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:175:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:175:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...
DEBUG:overwitch.c:175:(overwitch_o2j_reader): o2j: Can not read data from ring buffer. Replicating last sample...

There are no errors in there.

The message o2j: Can not read data from ring buffer. Replicating last sample... means that there are not enough data but this only happens at startup when both threads start reading and writing from the ring buffer. In this case, the JACK side has not enough data to read from the Overbridge side (o2j).

You didn't say if you were getting the overflow errors. Is it working now? Are the audio glitches still present?

On the other side of things, I've just pushed a few commits. These are the improvements and fixes.

  • Overwitch options are improved and are listed with -h.
  • Now, a device must be provided with the option -d. Hopefully, testing will be easier for you. (No support for several devices of the same type yet though.)
  • I've fixed the track amount in Analog Four MKII and Analog Rytm MKII in case someone clones this. I've improved the names as well.

I forgot to mention that, now, it's possible to have several instances of Overwitch running with several devices.

Any update on this? Did you sort the issue out?

During this time, a lot of improvements have been added. Now, you can try the -b option to reduce device lateny and increase the JACK buffer. Perhaps this would help.

Hi @CarlColglazier!

Did you get the time to test this again on another computer? Did you manage to make it work?

I'm on Debian version 11, which came out during August, and works quite well with Overwitch.

@CarlColglazier - could you check if these issues still exist on current master?

Other people is reporting that this is not happening any more Looks so I'm closing it.

Feel free to reopen it in case it's not.

Maybe this didn't get solved after all.

We are facing issues with the new Syntakt in #30 and looks that the underlying problem is the same as reported here and as it's affecting other devices with more than 2 inputs.

@dagargo I guess I'll start posting here.
cli_output.txt

From the latest patch you wanted me to apply

Once we get Syntakt fixed maybe I'll try it on my A4 and AH

Also should the title of the issue be on >2 inputs? I haven't had any issues with outputs on other devices

OK, let's try to fix this thing here.

I've just pushed a commit that sets the buffer size and sample rate before starting the resampler. It makes no difference for me but definitely thee could be issues regarding the initialization that could affect other systems (race conditions).

Let me know if this changes anything.

Also should the title of the issue be on >2 inputs?

Yes. It's renamed now. I let it be but it's the right time to change it.

Still distorted, although I noticed I got the overflow error before I even started connecting to the Syntakt inputs.
cli_output.txt

although I noticed I got the overflow error before I even started connecting to the Syntakt inputs.

Yeah, J2O audio is activated from startup now. Once we solve this, I'll probably reimplement it.

I have added overwitch-play to the j2o_always_on branch, which just plays some audio thru an Overbridge device.

I'd like you to try this. If this fails, post the -vv output as always. If it doesn't, the error is in the resampler.

Notice that the number of tracks must match the ones the device has, that's why I'm recording only the main L and main R channels. In your case, you should record 8 tracks, for the overwitch-playcommand to work.

$ overwitch-record -n 0 -m 11
^C255360 frames written
Digitakt_2022-06-05T15:56:07.wav file created

$ overwitch-play -n 0 Digitakt_2022-06-05T15\:56\:07.wav 
255360 frames read

Audio is still fairly distorted as usual, also I think I did the commands right.
overwitch-record -n 0 -m 0011111111 for tracks 1 to 8

cli_output.txt

The command looks right to me. You can always open the WAV file in Ardour and check it out. There should be 8 audio channels there.

This is good news because the problem is in the USB side, which means that the bug is in engine.c.

I've pushed a commit that adds a check for the transfer size. As per the documentation, this check should be performed always.

Could you try the same test again? You don't need to record the audio again.

Tested again and it doesn't seem like your new log message comes up
cli_output.txt

I've added a new log but, more importantly, I've set the USB transfer timeout to 5 ms. After re-reading the documentation, looks like a timeout of 0 would not report the timeouts at all, as it means no timeout.

Could you run the same test with overwitch-play again?

cli_output.txt

The errors are transfer timeouts based on this edit

{
      error_print ("p2o: Error on USB audio transfer: %s, %d, %s\n",
		   libusb_error_name (xfr->status), xfr->status, libusb_strerror (xfr->status));
    }

and the error was

ERROR:engine.c:333:(cb_xfr_audio_out): p2o: Error on USB audio transfer: LIBUSB_TRANSFER_TIMED_OUT, 2, Other error
DEBUG:main-play.c:77:(buffer_read): Reading 5376 bytes (168 frames) from file...

That is a breakthrough!

Captura de pantalla de 2022-06-06 18-04-43

I was checking a few things and I realized that the packets are not captured in the same order in Wireshark. In the image, the left side is Overbridge (Windows); the right is Overbridge (Linux).

In Overbridge, packets are always in pairs. Not sure if this the underlying issue here (if could be also the way Windows shows these) but I can confirm that on Linux the packets do not always go in pairs.

Perhaps Digitakt and Digitone are implemented in a way that make them robust in this regard.

I was doing some tests and realize this change makes the packets go in pairs

diff --git a/src/engine.c b/src/engine.c
index ac5ec0a..6a9d8bc 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -931,14 +931,6 @@ run_audio_o2p_midi (void *data)
 
   //status == OW_ENGINE_STATUS_BOOT
 
-  //Both these calls always need to be called and can not be skipped.
-  prepare_cycle_in_audio (engine);
-  prepare_cycle_out_audio (engine);
-  if (engine->context->options & OW_ENGINE_OPTION_O2P_MIDI)
-    {
-      prepare_cycle_in_midi (engine);
-    }
-
   while (1)
     {
       engine->p2o_latency = 0;
@@ -964,6 +956,14 @@ run_audio_o2p_midi (void *data)
        }
       pthread_spin_unlock (&engine->lock);
 
+      prepare_cycle_out_audio (engine);
+      libusb_handle_events_completed (engine->usb.context, NULL);
+      prepare_cycle_in_audio (engine);
+      if (engine->context->options & OW_ENGINE_OPTION_O2P_MIDI)
+        {
+          prepare_cycle_in_midi (engine);
+        }
+
       while (ow_engine_get_status (engine) >= OW_ENGINE_STATUS_WAIT)
        {
          libusb_handle_events_completed (engine->usb.context, NULL);

Does this change make any difference to you?

That change cut out all of the audio, though the logs seem to output a similar error
cli_output.2.txt

Let's undo the last step then.

Does it make any difference increasing this?

#define XFR_TIMEOUT 5

With a value of 1, I've got the same error for input and output, which makes sense anyway.

ERROR:engine.c:312:(cb_xfr_audio_in): o2p: Error on USB audio transfer (2, LIBUSB_TRANSFER_TIMED_OUT): Other error
ERROR:engine.c:334:(cb_xfr_audio_out): p2o: Error on USB audio transfer (2, LIBUSB_TRANSFER_TIMED_OUT): Other error

Oh I did play around with that value before that previous patch, tried 20 and 100 and it was the same result.

Another idea.

The option LIBUSB_TRANSFER_ADD_ZERO_PACKET adds a zero-length packet. This is useful if the device needs an empty packet to signal the end. It might be our case but my Digitakt works as always.

$ git diff
diff --git a/src/engine.c b/src/engine.c
index ac5ec0a..3f8350b 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -77,6 +77,7 @@ prepare_transfers (struct ow_engine *engine)
     {
       return -ENOMEM;
     }
+  engine->usb.xfr_audio_out->flags = LIBUSB_TRANSFER_ADD_ZERO_PACKET;
 
   engine->usb.xfr_midi_in = libusb_alloc_transfer (0);
   if (!engine->usb.xfr_midi_in)

Could you try this patch?

cli_output.txt

Still not working.

Could you try again with LIBUSB_DEBUG=4 overwitch -vvv? Perhaps, we saw something there.

I've just learnt about this feature of libusb, sorry.

All good mate, here ya go.
cli_outputs.zip

You know I just realised, I don't think I ever described what the distortion was like until I let overwitch_play played the entire sample I recorded with overwitch_record. It gets extremely noisy and a lot of the audio gets cut out, but you can kinda make out some basic sounds like the beat and what not. It also slows down a bit noticably (e.g. overwitch_play was playing my sample for 21~ seconds when the sample was only 14 seconds as recorded in the logs attached above). I hoped this gave you some sort of insight. I'm trying to record it but I'm not too familiar with how to do it in jack.

It's been like this with my A4, AH and now the Syntakt.

As I can not reproduce the error with my setup, I can not try the obvious stuff.

As per the documentation here, it's stated that success, error, cancelation and timeout are the possible completion status of a transfer; so a timeout is different than an error. I've been researching about this but I haven't found anything interesting.

As we're only facing the timeout errors, this would be enough to skip to prepare a new out cycle in this scenario.

$ git diff
diff --git a/src/engine.c b/src/engine.c
index b66ebb9..7530eee 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -332,6 +332,7 @@ cb_xfr_audio_out (struct libusb_transfer *xfr)
     {
       error_print ("p2o: Error on USB audio transfer: %s\n",
                   libusb_error_name (xfr->status));
+      return;
     }
 
   struct ow_engine *engine = xfr->user_data;

The previous assumption was wrong.

The timeouts section here says this.

When a transfer times out, libusb internally notes this and attempts to cancel the transfer.

So the status will be timeout but the transfer will be already canceled.

I was told that the USB configuration is the same but I don't know what to think anymore.

What is the output of lsusb? This is the output of my Digitakt. Interface 1, alternate setting 3, endpoint 0x83 is where the host is gonna write audio to; and interface 2, alternate setting 2, endpoint 0x03 is where the host is gonna read audio from.

$ lsusb | grep Elektron
Bus 001 Device 011: ID 1935:000c Elektron Music Machines Digitakt Overbridge
$ lsusb -d 1935:000c -v
Bus 001 Device 011: ID 1935:000c Elektron Music Machines Digitakt Overbridge
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x1935 Elektron Music Machines
  idProduct          0x000c Digitakt Overbridge
  bcdDevice            0.01
  iManufacturer           1 Elektron Music Machines
  iProduct                2 Elektron Digitakt
  iSerial                 3 000000000001
  bNumConfigurations      2
[...]
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       3
      bNumEndpoints           1
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0170  1x 368 bytes
        bInterval               1
[...]
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       2
      bNumEndpoints           1
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0058  1x 88 bytes
        bInterval               1
[...]

The interesting parts are the endpoints used. I'll check it against the Wireshark captures in Windows.

BTW, with this alternate settings my Digitakt works too.

$ git diff
diff --git a/src/engine.c b/src/engine.c
index b66ebb9..7cebdce 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -618,7 +618,7 @@ ow_engine_init (struct ow_engine *engine, int blocks_per_transfer)
       ret = OW_USB_ERROR_CANT_CLAIM_IF;
       goto end;
     }
-  err = libusb_set_interface_alt_setting (engine->usb.device_handle, 2, 2);
+  err = libusb_set_interface_alt_setting (engine->usb.device_handle, 2, 3);
   if (LIBUSB_SUCCESS != err)
     {
       ret = OW_USB_ERROR_CANT_SET_ALT_SETTING;

But the definition of the alternate settings 2 and 3 is exactly the same, which by my very limited understanding of USB makes no sense.

Do you have any other alternate setting for the endpoint address 0x03? Could you try those?

lsusb.txt
Heya, here's my output for lsusb. I'll try out the alt setting change in a bit.

Uhhhhh, setting it to 3 worked... Wow.

According to the lsusb output I have, I assume with the higher number of inputs it'd require a bigger packet size? It seems on yours and my lsusb output number 3 has a higher max packet size

Yeahhhhhh
2022-06-10_202811
This is with Pipewire

This is really really great! After such a long time audio input is finally working for every Overbridge 2 device! 🎉

Thanks to all of you for being so patient and responsive!

After merging a couple of PRs into the j2o_always_on brach, this has been merged into master.

Still to be confirmed on Analog Rytm MKII and Digitone. @CarlColglazier, could do try to check the master branch with these machines?

Nice! I can also do some testing with the Sy takt and PipeWire as soon as I get mine back next week.

BTW, Digitone reported to work by @serratedserenade with the alt setting 3 too. I'm assuming it will work with the keys for now.

At the USB level, the both Heats are the same so we can assume that too.

The only remaining machine to be confirmed is Rytm MKII. 🚀

I'll assume that Rytm MKII works too.