+ struct port_bridge *bridge = (struct port_bridge *)instance;
+ struct port_bridge_member *member = bridge->first;
+ unsigned long long timer_time;
+ signed long *sum, sample;
+ unsigned char buffer[160], *buf, *d;
+ int i, read_p, space;
+
+ bridge->sample_count += 160;
+
+ /* schedule exactly 20ms from last schedule */
+ timer_time = timer->timeout.tv_sec * MICRO_SECONDS + timer->timeout.tv_usec;
+ timer_time += 20000; /* 20 MS */
+ timer->timeout.tv_sec = timer_time / MICRO_SECONDS;
+ timer->timeout.tv_usec = timer_time % MICRO_SECONDS;
+ timer->active = 1;
+
+ while (member) {
+ /* calculate transmit data */
+ read_p = bridge->read_p;
+ sum = bridge->sum_buffer;
+ buf = member->buffer;
+ d = buffer;
+ for (i = 0; i < 160; i++) {
+ sample = sum[read_p];
+ sample -= audio_law_to_s32[buf[read_p]];
+ buf[read_p] = silence;
+ if (sample < SHORT_MIN) sample = SHORT_MIN;
+ if (sample > SHORT_MAX) sample = SHORT_MAX;
+ *d++ = audio_s16_to_law[sample & 0xffff];
+ read_p = (read_p + 1) & (BRIDGE_BUFFER - 1);
+ }
+ /* send data */
+ member->port->bridge_rx(buffer, 160);
+ /* raise write pointer, if read pointer would overrun them */
+ space = ((member->write_p - bridge->read_p) & (BRIDGE_BUFFER - 1)) - 160;
+ if (space < 0) {
+ space = 0;
+ member->write_p = read_p;
+// PDEBUG(DEBUG_PORT, "bridge %u member %d has buffer underrun\n", bridge->bridge_id, member->port->p_serial);
+ }
+ /* find minimum delay */
+ if (space < member->min_space)
+ member->min_space = space;
+ /* check if we should reduce buffer */
+ if (bridge->sample_count >= 8000*5) {
+ /* reduce buffer by minimum delay */
+// PDEBUG(DEBUG_PORT, "bridge %u member %d has min space of %d samples\n", bridge->bridge_id, member->port->p_serial, member->min_space);
+ member->write_p = (member->write_p - member->min_space) & (BRIDGE_BUFFER - 1);
+ member->min_space = 1000000; /* infinite */
+ }
+ member = member->next;
+ }