mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	update for segments
This commit is contained in:
		
							parent
							
								
									f8c3126b52
								
							
						
					
					
						commit
						3daf9f85d2
					
				
					 1 changed files with 71 additions and 52 deletions
				
			
		| 
						 | 
					@ -706,11 +706,13 @@ static inline void debug_position(struct client *c, jack_position_t *p)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void jack_to_position(jack_position_t *s, struct spa_io_position *d)
 | 
					static inline void jack_to_position(jack_position_t *s, struct spa_io_position *pos)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct spa_io_segment *d = &pos->segments[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d->valid = 0;
 | 
						d->valid = 0;
 | 
				
			||||||
	if (s->valid & JackPositionBBT) {
 | 
						if (s->valid & JackPositionBBT) {
 | 
				
			||||||
		SPA_FLAG_SET(d->valid, SPA_IO_POSITION_VALID_BAR);
 | 
							SPA_FLAG_SET(d->valid, SPA_IO_SEGMENT_VALID_BAR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (s->valid & JackBBTFrameOffset)
 | 
							if (s->valid & JackBBTFrameOffset)
 | 
				
			||||||
			d->bar.offset = s->bbt_offset;
 | 
								d->bar.offset = s->bbt_offset;
 | 
				
			||||||
| 
						 | 
					@ -723,54 +725,59 @@ static inline void jack_to_position(jack_position_t *s, struct spa_io_position *
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void position_to_jack(struct spa_io_position *s, jack_position_t *d, jack_transport_state_t *state)
 | 
					static inline jack_transport_state_t position_to_jack(struct spa_io_position *s, jack_position_t *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						jack_transport_state_t state;
 | 
				
			||||||
 | 
						struct spa_io_segment *seg = &s->segments[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (s->state) {
 | 
						switch (s->state) {
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
	case SPA_IO_POSITION_STATE_STOPPED:
 | 
						case SPA_IO_POSITION_STATE_STOPPED:
 | 
				
			||||||
		*state = JackTransportStopped;
 | 
							state = JackTransportStopped;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SPA_IO_POSITION_STATE_STARTING:
 | 
						case SPA_IO_POSITION_STATE_STARTING:
 | 
				
			||||||
		*state = JackTransportStarting;
 | 
							state = JackTransportStarting;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SPA_IO_POSITION_STATE_RUNNING:
 | 
						case SPA_IO_POSITION_STATE_RUNNING:
 | 
				
			||||||
		*state = JackTransportRolling;
 | 
							if (seg->flags & SPA_IO_SEGMENT_FLAG_LOOPING)
 | 
				
			||||||
		break;
 | 
								state = JackTransportLooping;
 | 
				
			||||||
	case SPA_IO_POSITION_STATE_LOOPING:
 | 
							else
 | 
				
			||||||
		*state = JackTransportLooping;
 | 
								state = JackTransportRolling;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (d == NULL)
 | 
				
			||||||
 | 
							return state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d->unique_1++;
 | 
						d->unique_1++;
 | 
				
			||||||
	d->usecs = s->clock.nsec / SPA_NSEC_PER_USEC;
 | 
						d->usecs = s->clock.nsec / SPA_NSEC_PER_USEC;
 | 
				
			||||||
	d->frame_rate = s->clock.rate.denom;
 | 
						d->frame_rate = s->clock.rate.denom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (s->clock.position >= s->clock_start &&
 | 
						if (s->clock.position >= seg->clock_start &&
 | 
				
			||||||
	    (s->clock_duration == 0 || s->clock.position < s->clock_start + s->clock_duration))
 | 
						    (seg->clock_duration == 0 || s->clock.position < seg->clock_start + seg->clock_duration))
 | 
				
			||||||
		d->frame = (s->clock.position - s->clock_start) * s->rate + s->position;
 | 
							d->frame = (s->clock.position - seg->clock_start) * seg->rate + seg->position;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		d->frame = s->position;
 | 
							d->frame = seg->position;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d->valid = 0;
 | 
						d->valid = 0;
 | 
				
			||||||
 | 
						if (seg->valid & SPA_IO_SEGMENT_VALID_BAR) {
 | 
				
			||||||
	if (s->valid & SPA_IO_POSITION_VALID_BAR) {
 | 
					 | 
				
			||||||
		double min;
 | 
							double min;
 | 
				
			||||||
		long abs_tick, abs_beat;
 | 
							long abs_tick, abs_beat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		d->valid |= JackPositionBBT;
 | 
							d->valid |= JackPositionBBT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		d->bbt_offset = s->bar.offset;
 | 
							d->bbt_offset = seg->bar.offset;
 | 
				
			||||||
		if (s->bar.offset)
 | 
							if (seg->bar.offset)
 | 
				
			||||||
			d->valid |= JackBBTFrameOffset;
 | 
								d->valid |= JackBBTFrameOffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		d->beats_per_bar = s->bar.signature_num;
 | 
							d->beats_per_bar = seg->bar.signature_num;
 | 
				
			||||||
		d->beat_type = s->bar.signature_denom;
 | 
							d->beat_type = seg->bar.signature_denom;
 | 
				
			||||||
		d->ticks_per_beat = 1920.0f;
 | 
							d->ticks_per_beat = 1920.0f;
 | 
				
			||||||
		d->beats_per_minute = s->bar.bpm;
 | 
							d->beats_per_minute = seg->bar.bpm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		min = d->frame / ((double) d->frame_rate * 60.0);
 | 
							min = d->frame / ((double) d->frame_rate * 60.0);
 | 
				
			||||||
                abs_tick = min * d->beats_per_minute * d->ticks_per_beat;
 | 
					                abs_tick = min * d->beats_per_minute * d->ticks_per_beat;
 | 
				
			||||||
		abs_beat = s->bar.beat;
 | 
							abs_beat = seg->bar.beat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		d->bar = abs_beat / d->beats_per_bar;
 | 
							d->bar = abs_beat / d->beats_per_bar;
 | 
				
			||||||
		d->beat = abs_beat - (d->bar * d->beats_per_bar) + 1;
 | 
							d->beat = abs_beat - (d->bar * d->beats_per_bar) + 1;
 | 
				
			||||||
| 
						 | 
					@ -780,6 +787,7 @@ static inline void position_to_jack(struct spa_io_position *s, jack_position_t *
 | 
				
			||||||
		d->bar++;
 | 
							d->bar++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	d->unique_2 = d->unique_1;
 | 
						d->unique_2 = d->unique_1;
 | 
				
			||||||
 | 
						return state;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -813,7 +821,7 @@ on_rtsocket_condition(void *data, int fd, uint32_t mask)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nsec = pos->clock.nsec;
 | 
							nsec = pos->clock.nsec;
 | 
				
			||||||
		c->activation->status = AWAKE;
 | 
							c->activation->status = PW_NODE_ACTIVATION_AWAKE;
 | 
				
			||||||
		c->activation->awake_time = nsec;
 | 
							c->activation->awake_time = nsec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		buffer_size = pos->clock.duration;
 | 
							buffer_size = pos->clock.duration;
 | 
				
			||||||
| 
						 | 
					@ -832,7 +840,7 @@ on_rtsocket_condition(void *data, int fd, uint32_t mask)
 | 
				
			||||||
				c->srate_callback(c->sample_rate, c->srate_arg);
 | 
									c->srate_callback(c->sample_rate, c->srate_arg);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		position_to_jack(pos, &jack_position, &jack_state);
 | 
							jack_state = position_to_jack(pos, &jack_position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (c->sync_callback && c->sync_emit) {
 | 
							if (c->sync_callback && c->sync_emit) {
 | 
				
			||||||
			c->sync_callback(jack_state,
 | 
								c->sync_callback(jack_state,
 | 
				
			||||||
| 
						 | 
					@ -871,7 +879,7 @@ on_rtsocket_condition(void *data, int fd, uint32_t mask)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		clock_gettime(CLOCK_MONOTONIC, &ts);
 | 
							clock_gettime(CLOCK_MONOTONIC, &ts);
 | 
				
			||||||
		nsec = SPA_TIMESPEC_TO_NSEC(&ts);
 | 
							nsec = SPA_TIMESPEC_TO_NSEC(&ts);
 | 
				
			||||||
		c->activation->status = FINISHED;
 | 
							c->activation->status = PW_NODE_ACTIVATION_FINISHED;
 | 
				
			||||||
		c->activation->finish_time = nsec;
 | 
							c->activation->finish_time = nsec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cmd = 1;
 | 
							cmd = 1;
 | 
				
			||||||
| 
						 | 
					@ -887,7 +895,7 @@ on_rtsocket_condition(void *data, int fd, uint32_t mask)
 | 
				
			||||||
					state->pending, state->required);
 | 
										state->pending, state->required);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (pw_node_activation_state_dec(state, 1)) {
 | 
								if (pw_node_activation_state_dec(state, 1)) {
 | 
				
			||||||
				l->activation->status = TRIGGERED;
 | 
									l->activation->status = PW_NODE_ACTIVATION_TRIGGERED;
 | 
				
			||||||
				l->activation->signal_time = nsec;
 | 
									l->activation->signal_time = nsec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				pw_log_trace(NAME" %p: signal %p %p", c, l, state);
 | 
									pw_log_trace(NAME" %p: signal %p %p", c, l, state);
 | 
				
			||||||
| 
						 | 
					@ -2345,8 +2353,8 @@ jack_nframes_t jack_get_buffer_size (jack_client_t *client)
 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
int jack_engine_takeover_timebase (jack_client_t *client)
 | 
					int jack_engine_takeover_timebase (jack_client_t *client)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pw_log_warn(NAME" %p: not implemented", client);
 | 
						pw_log_error(NAME" %p: deprecated", client);
 | 
				
			||||||
	return -ENOTSUP;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
| 
						 | 
					@ -3290,6 +3298,14 @@ int  jack_set_timebase_callback (jack_client_t *client,
 | 
				
			||||||
				 void *arg)
 | 
									 void *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct client *c = (struct client *) client;
 | 
						struct client *c = (struct client *) client;
 | 
				
			||||||
 | 
						struct pw_node_activation *a = c->driver_activation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (a == NULL)
 | 
				
			||||||
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c->timebase_callback = timebase_callback;
 | 
						c->timebase_callback = timebase_callback;
 | 
				
			||||||
	c->timebase_arg = arg;
 | 
						c->timebase_arg = arg;
 | 
				
			||||||
	c->timebase_emit = true;
 | 
						c->timebase_emit = true;
 | 
				
			||||||
| 
						 | 
					@ -3314,9 +3330,9 @@ jack_transport_state_t jack_transport_query (const jack_client_t *client,
 | 
				
			||||||
	struct pw_node_activation *a = c->driver_activation;
 | 
						struct pw_node_activation *a = c->driver_activation;
 | 
				
			||||||
	jack_transport_state_t jack_state = JackTransportStopped;
 | 
						jack_transport_state_t jack_state = JackTransportStopped;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (a != NULL && pos != NULL)
 | 
						if (a != NULL)
 | 
				
			||||||
		position_to_jack(&a->position, pos, &jack_state);
 | 
							jack_state = position_to_jack(&a->position, pos);
 | 
				
			||||||
	else
 | 
						else if (pos != NULL)
 | 
				
			||||||
		memset(pos, 0, sizeof(jack_position_t));
 | 
							memset(pos, 0, sizeof(jack_position_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return jack_state;
 | 
						return jack_state;
 | 
				
			||||||
| 
						 | 
					@ -3328,14 +3344,14 @@ jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client)
 | 
				
			||||||
	struct client *c = (struct client *) client;
 | 
						struct client *c = (struct client *) client;
 | 
				
			||||||
	struct pw_node_activation *a = c->driver_activation;
 | 
						struct pw_node_activation *a = c->driver_activation;
 | 
				
			||||||
	struct spa_io_position *pos;
 | 
						struct spa_io_position *pos;
 | 
				
			||||||
 | 
						struct spa_io_segment *seg;
 | 
				
			||||||
	uint64_t clock_position;
 | 
						uint64_t clock_position;
 | 
				
			||||||
	if (!a)
 | 
						if (!a)
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pos = &a->position;
 | 
						pos = &a->position;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pos->state == SPA_IO_POSITION_STATE_RUNNING ||
 | 
						if (pos->state == SPA_IO_POSITION_STATE_RUNNING) {
 | 
				
			||||||
	    pos->state == SPA_IO_POSITION_STATE_LOOPING) {
 | 
					 | 
				
			||||||
		struct timespec ts;
 | 
							struct timespec ts;
 | 
				
			||||||
		clock_gettime(CLOCK_MONOTONIC, &ts);
 | 
							clock_gettime(CLOCK_MONOTONIC, &ts);
 | 
				
			||||||
		uint64_t nsecs = SPA_TIMESPEC_TO_NSEC(&ts) - pos->clock.nsec;
 | 
							uint64_t nsecs = SPA_TIMESPEC_TO_NSEC(&ts) - pos->clock.nsec;
 | 
				
			||||||
| 
						 | 
					@ -3344,7 +3360,9 @@ jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		clock_position = pos->clock.position;
 | 
							clock_position = pos->clock.position;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return (pos->clock_start - clock_position) * pos->rate + pos->position;
 | 
						seg = &pos->segments[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (seg->clock_start - clock_position) * seg->rate + seg->position;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
| 
						 | 
					@ -3364,33 +3382,40 @@ int  jack_transport_reposition (jack_client_t *client,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		seq1 = SEQ_WRITE(&a->pending.seq);
 | 
							seq1 = SEQ_WRITE(&a->pending.seq);
 | 
				
			||||||
		a->pending.change_mask |= UPDATE_POSITION;
 | 
							a->pending.change_mask |= PW_NODE_ACTIVATION_UPDATE_REPOSITION;
 | 
				
			||||||
		a->pending.position.position = pos->frame;
 | 
							a->pending.segment.flags = 0;
 | 
				
			||||||
		a->pending.position.clock_start = 0;
 | 
							a->pending.segment.clock_start = 0;
 | 
				
			||||||
		a->pending.position.clock_duration = 0;
 | 
							a->pending.segment.clock_duration = 0;
 | 
				
			||||||
		a->pending.position.rate = 1.0;
 | 
							a->pending.segment.position = pos->frame;
 | 
				
			||||||
 | 
							a->pending.segment.rate = 1.0;
 | 
				
			||||||
		seq2 = SEQ_WRITE(&a->pending.seq);
 | 
							seq2 = SEQ_WRITE(&a->pending.seq);
 | 
				
			||||||
	} while (!SEQ_WRITE_SUCCESS(seq1, seq2));
 | 
						} while (!SEQ_WRITE_SUCCESS(seq1, seq2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void update_state(struct pw_node_activation *a, enum spa_io_position_state state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t seq1, seq2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							seq1 = SEQ_WRITE(&a->pending.seq);
 | 
				
			||||||
 | 
							a->pending.change_mask |= PW_NODE_ACTIVATION_UPDATE_STATE;
 | 
				
			||||||
 | 
							a->pending.state = state;
 | 
				
			||||||
 | 
							seq2 = SEQ_WRITE(&a->pending.seq);
 | 
				
			||||||
 | 
						} while (!SEQ_WRITE_SUCCESS(seq1, seq2));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
void jack_transport_start (jack_client_t *client)
 | 
					void jack_transport_start (jack_client_t *client)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct client *c = (struct client *) client;
 | 
						struct client *c = (struct client *) client;
 | 
				
			||||||
	struct pw_node_activation *a = c->driver_activation;
 | 
						struct pw_node_activation *a = c->driver_activation;
 | 
				
			||||||
	uint32_t seq1, seq2;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!a)
 | 
						if (!a)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						update_state(a, SPA_IO_POSITION_STATE_STARTING);
 | 
				
			||||||
		seq1 = SEQ_WRITE(&a->pending.seq);
 | 
					 | 
				
			||||||
		a->pending.change_mask |= UPDATE_STATE;
 | 
					 | 
				
			||||||
		a->pending.state = SPA_IO_POSITION_STATE_STARTING;
 | 
					 | 
				
			||||||
		seq2 = SEQ_WRITE(&a->pending.seq);
 | 
					 | 
				
			||||||
	} while (!SEQ_WRITE_SUCCESS(seq1, seq2));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
| 
						 | 
					@ -3398,17 +3423,11 @@ void jack_transport_stop (jack_client_t *client)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct client *c = (struct client *) client;
 | 
						struct client *c = (struct client *) client;
 | 
				
			||||||
	struct pw_node_activation *a = c->driver_activation;
 | 
						struct pw_node_activation *a = c->driver_activation;
 | 
				
			||||||
	uint32_t seq1, seq2;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!a)
 | 
						if (!a)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						update_state(a, SPA_IO_POSITION_STATE_STOPPED);
 | 
				
			||||||
		seq1 = SEQ_WRITE(&a->pending.seq);
 | 
					 | 
				
			||||||
		a->pending.change_mask |= UPDATE_STATE;
 | 
					 | 
				
			||||||
		a->pending.state = SPA_IO_POSITION_STATE_STOPPED;
 | 
					 | 
				
			||||||
		seq2 = SEQ_WRITE(&a->pending.seq);
 | 
					 | 
				
			||||||
	} while (!SEQ_WRITE_SUCCESS(seq1, seq2));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue