void ClientNode::_DataAvailable(bigtime_t time) { size_t samples = fFormat.u.raw_audio.buffer_size / sizeof(float); fFramesSent += samples; JackPortList* ports = fOwner->GetOutputPorts(); for (int i = 0; i < ports->CountItems(); i++) { JackPort* port = ports->ItemAt(i); if (port != NULL && port->IsConnected()) { BBuffer* buffer = FillNextBuffer(time, port); if (buffer) { if (SendBuffer(buffer, port->MediaOutput()->source, port->MediaOutput()->destination) != B_OK) { printf("ClientNode::_DataAvailable: Buffer sending " "failed\n"); buffer->Recycle(); } size_t nFrames = fFormat.u.raw_audio.buffer_size / ((fFormat.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK) * fFormat.u.raw_audio.channel_count); } if (buffer == NULL) return; } } }
void ClientNode::Connect(status_t status, const media_source &src, const media_destination &dst, const media_format &format, char* name) { if (status != B_OK) return; media_node_id id; FindLatencyFor(dst, &fDownstreamLatency, &id); fOwner->SetFormat(format); JackPort* port; JackPortList* outputs = fOwner->GetOutputPorts(); for (int i = 0; i < outputs->CountItems(); i++) { port = outputs->ItemAt(i); BString str(jack_port_name((jack_port_t*) port)); if (str.Compare(name) == 0 && !port->IsConnected()) { printf("ClientNode::Connect %s\n", port->Name()); port->MediaOutput()->source = src; port->MediaOutput()->destination = dst; port->MediaOutput()->format = format; break; } } }
JackPort* ClientNode::_FindOutputPort(media_source source, media_destination dest) const { JackPort* port; JackPortList* outputs = fOwner->GetOutputPorts(); for (int i = 0; i < outputs->CountItems(); i++) { port = outputs->ItemAt(i); if (source == port->MediaOutput()->source && dest == port->MediaOutput()->destination) return port; } }
void ClientNode::ProducerDataStatus(const media_destination &dst, int32 status, bigtime_t when) { printf("ClientNode::ProducerDataStatus(\n"); JackPortList* ports = fOwner->GetOutputPorts(); for (int i = 0; i < ports->CountItems(); i++) { JackPort* port = ports->ItemAt(i); if (port->MediaOutput()->destination != media_destination::null) SendDataStatus(status, port->MediaOutput()->destination, when); } }
JackPort* JackClient::PortByName(const char* name) { JackPort* port; JackPortList* lst = GetOutputPorts(); for (int i = 0; i < lst->CountItems(); i++) { port = lst->ItemAt(i); BString str(name); if (str.Compare(jack_port_name((jack_port_t*)port)) == 0) return port; } return NULL; }
void ClientNode::Disconnect(const media_source &src, const media_destination &dst) { printf("ClientNode::Disconnect\n"); JackPort* port; JackPortList* outputs = fOwner->GetOutputPorts(); for (int i = 0; i < outputs->CountItems(); i++) { port = outputs->ItemAt(i); if (port->MediaOutput()->source == src && port->MediaOutput()->destination == dst) { port->SetConnected(false); } } }
status_t ClientNode::PrepareToConnect(const media_source &src, const media_destination &dst, media_format *format, media_source *out_source, char *name) { printf("ClientNode::PrepareToConnect\n"); if (dst.port == ControlPort()) return B_MEDIA_BAD_SOURCE; if (src.port != ControlPort() || src.id != 0) return B_MEDIA_BAD_SOURCE; if (format->type != B_MEDIA_RAW_AUDIO && format->type != B_MEDIA_UNKNOWN_TYPE) { return B_MEDIA_BAD_FORMAT; } JackPort* port; JackPortList* outputs = fOwner->GetOutputPorts(); for (int i = 0; i < outputs->CountItems(); i++) { port = outputs->ItemAt(i); media_output* output = port->MediaOutput(); if (output->source.id == src.id && output->destination.id == dst.id) { if (port->IsConnected()) return B_MEDIA_ALREADY_CONNECTED; *out_source = src; BString portName(jack_port_name((jack_port_t*) port)); portName.CopyInto(name, 0, portName.Length()); printf("Connecting to %s\n", name); format->SpecializeTo(&fFormat); return B_OK; } } return B_MEDIA_BAD_SOURCE; }
status_t ClientNode::GetNextOutput(int32 *cookie, media_output *output) { //printf("ClientNode::GetNextOutput %d\n", *cookie); JackPortList* ports = fOwner->GetOutputPorts(); if (*cookie >= ports->CountItems()) return B_BAD_INDEX; JackPort* port = ports->ItemAt(*cookie); if (port == NULL) return B_BAD_INDEX; *output = *port->MediaOutput(); *cookie += 1; return B_OK; }
bool JackClient::PortsReady() const { if(!fOpen && !fActivated) return false; JackPortList* lst = GetOutputPorts(); for (int i = 0; i < lst->CountItems(); i++) { JackPort* port = lst->ItemAt(i); if (!port->IsConnected()) return false; } lst = GetInputPorts(); for (int i = 0; i < lst->CountItems(); i++) { JackPort* port = lst->ItemAt(i); if (!port->IsConnected()) return false; } return true; }
status_t ClientNode::_InitOutputPorts() { //printf("JackClient::_InitOutputPorts()\n"); JackPortList* outputPorts = fOwner->GetOutputPorts(); for (int i = 0; i < outputPorts->CountItems(); i++) { JackPort* port = outputPorts->ItemAt(i); if (!port->IsConnected()) return B_ERROR; BBuffer* buffer = fBufferGroup->RequestBuffer( fFormat.u.raw_audio.buffer_size); if (buffer == NULL || buffer->Data() == NULL) { printf("RequestBuffer failed\n"); return B_ERROR; } port->SetProcessingBuffer(buffer); } return B_OK; }
void ClientNode::HandleEvent(const media_timed_event *event, bigtime_t late, bool realTimeEvent) { //printf("ClientNode::HandleEvent %d\n", event->type); switch (event->type) { case BTimedEventQueue::B_HANDLE_BUFFER: { printf("BTimedEventQueue::B_HANDLE_BUFFER\n"); break; } case BTimedEventQueue::B_START: { printf("BTimedEventQueue::B_START\n"); if (RunState() != B_STARTED) { fFramesSent = 0; fTime = TimeSource()->RealTime(); int period = (fOwner->GetOutputPorts()->CountItems())*3; fBufferGroup = new BBufferGroup(fFormat.u.raw_audio.buffer_size, period); if (fBufferGroup->InitCheck() != B_OK) printf("error\n"); bigtime_t start = ::system_time(); ComputeCycle(); bigtime_t produceLatency = ::system_time(); fProcessLatency = produceLatency - start; printf("Estimated latency is %Ld\n", fProcessLatency); JackPortList* outputPorts = fOwner->GetOutputPorts(); for (int i = 0; i < outputPorts->CountItems(); i++) { JackPort* port = outputPorts->ItemAt(i); port->CurrentBuffer()->Recycle(); } int sample_size = (fFormat.u.raw_audio.format & 0xf)* fFormat.u.raw_audio.channel_count; bigtime_t duration = bigtime_t(1000000) * fOwner->BufferSize() / bigtime_t(fFormat.u.raw_audio.frame_rate); SetBufferDuration(duration); SetEventLatency(fDownstreamLatency + fProcessLatency); _ScheduleOutputEvent(fTime); } break; } case BTimedEventQueue::B_STOP: { // stopped - don't process any more buffers, flush all buffers // from event queue EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER); Stop(TimeSource()->Now(), true); NodeStopped(TimeSource()->Now()); break; } case BTimedEventQueue::B_DATA_STATUS: { break; } case NEW_BUFFER_EVENT: { ComputeCycle(); _DataAvailable(event->event_time); // Now we schedule the next event bigtime_t nextEvent = fTime + bigtime_t((1000000LL * fFramesSent) / (int32)fFormat.u.raw_audio.frame_rate)+EventLatency(); _ScheduleOutputEvent(nextEvent); break; } default: break; } }