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; } } }
int JackPortAudioDriver::Attach() { if (JackAudioDriver::Attach() == 0) { const char* alias; if (fInputDevice != paNoDevice && fPaDevices->GetHostFromDevice(fInputDevice) == "ASIO") { for (int i = 0; i < fCaptureChannels; i++) { if (PaAsio_GetInputChannelName(fInputDevice, i, &alias) == paNoError) { JackPort* port = fGraphManager->GetPort(fCapturePortList[i]); port->SetAlias(alias); } } } if (fOutputDevice != paNoDevice && fPaDevices->GetHostFromDevice(fOutputDevice) == "ASIO") { for (int i = 0; i < fPlaybackChannels; i++) { if (PaAsio_GetOutputChannelName(fOutputDevice, i, &alias) == paNoError) { JackPort* port = fGraphManager->GetPort(fPlaybackPortList[i]); port->SetAlias(alias); } } } return 0; } else { return -1; } }
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; } } }
void JackAlsaDriver::MonitorInputAux() { for (int chn = 0; chn < fCaptureChannels; chn++) { JackPort* port = fGraphManager->GetPort(fCapturePortList[chn]); if (port->MonitoringInput()) { ((alsa_driver_t *)fDriver)->input_monitor_mask |= (1 << chn); } } }
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; } }
int JackWinMMEDriver::Attach() { JackPort* port; jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; MMRESULT res; int i; jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (i = 0; i < fCaptureChannels; i++) { MIDIINCAPS caps; res = midiInGetDevCaps(fMidiDestination[i].fIndex, &caps, sizeof(caps)); if (res == MMSYSERR_NOERROR) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); } else { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); } snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fCapturePortList[i] = port_index; jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } for (i = 0; i < fPlaybackChannels; i++) { MIDIOUTCAPS caps; res = midiOutGetDevCaps(fMidiSource[i].fIndex, &caps, sizeof(caps)); if (res == MMSYSERR_NOERROR) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); } else { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fPlaybackDriverName, i + 1); } snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fPlaybackPortList[i] = port_index; jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } return 0; }
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); } }
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); } } }
int JackClient::ConnectPorts(const char* source, const char* destination) { media_node sourceNode = FindNativeNode(source); media_node destNode = FindNativeNode(destination); JackPort* port = PortByName(source); if (port == NULL) printf("port is NULL\n"); printf("%s\n", port->Name()); media_source src(sourceNode.port, 0); media_format format; format.type = B_MEDIA_RAW_AUDIO; format.u.raw_audio.buffer_size = fFormat.u.raw_audio.buffer_size; format.u.raw_audio = media_raw_audio_format::wildcard; format.u.raw_audio.channel_count = 1; format.u.raw_audio.format = WRAPPER_PREFERRED_FORMAT; media_destination dest(destNode.port, 0); media_output* output = port->MediaOutput(); output->node = sourceNode; output->source = src; output->destination = dest; output->format = format; strcpy(output->name, source); media_input* input = port->MediaInput(); input->node = destNode; input->source = src; input->destination = dest; input->format = format; strcpy(input->name, destination); if (status_t ret = fRoster->Connect(src, dest, &format, output, input) != B_OK) { printf("error connecting %s\n", strerror(ret)); return -1; } port->SetConnected(true); return 0; }
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; }
int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { jack_log("JackEngine::PortDisconnect ref = %d src = %d dst = %d", refnum, src, dst); if (dst == ALL_PORTS) { jack_int_t connections[CONNECTION_NUM_FOR_PORT]; fGraphManager->GetConnections(src, connections); JackPort* port = fGraphManager->GetPort(src); int res = 0; if (port->GetFlags() & JackPortIsOutput) { for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && (connections[i] != EMPTY); i++) { if (PortDisconnect(refnum, src, connections[i]) != 0) { res = -1; } } } else { for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && (connections[i] != EMPTY); i++) { if (PortDisconnect(refnum, connections[i], src) != 0) { res = -1; } } } return res; } if (fGraphManager->CheckPorts(src, dst) < 0) { return -1; } int res = CheckPortsConnect(refnum, src, dst); if (res != 1) { return res; } res = fGraphManager->Disconnect(src, dst); if (res == 0) NotifyPortConnect(src, dst, false); return res; }
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; }
int JackMidiDriver::Attach() { JackPort* port; jack_port_id_t port_index; char name[REAL_JACK_PORT_NAME_SIZE]; char alias[REAL_JACK_PORT_NAME_SIZE]; int i; jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fCapturePortList[i] = port_index; jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } for (i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fPlaybackPortList[i] = port_index; jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } UpdateLatencies(); return 0; }
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; }
jack_port_t* JackClient::RegisterPort(const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size) { unsigned long size; if (buffer_size == 0) { if (strcmp(port_type, JACK_DEFAULT_AUDIO_TYPE) == 0) { size = fFormat.u.raw_audio.buffer_size; } else if (strcmp(port_type, JACK_DEFAULT_MIDI_TYPE) == 0) { // not supported atm return NULL; } } else size = buffer_size; JackPort* port = new JackPort(port_name, port_type, flags, size, this); if (flags & JackPortIsInput) fInputPorts->AddItem(port); else if (flags & JackPortIsOutput) fOutputPorts->AddItem(port); media_output* output = port->MediaOutput(); output->node = fClientNode->Node(); output->source.port = fClientNode->ControlPort(); output->source.id = 0; output->destination = media_destination::null; output->format = fFormat; strcpy(output->name, jack_port_name((jack_port_t*)port)); return (jack_port_t*) port; }
int JackClient::PortIsMine(jack_port_id_t port_index) { JackPort* port = GetGraphManager()->GetPort(port_index); return GetClientControl()->fRefNum == port->GetRefNum(); }
int JackClient::HandleLatencyCallback(int status) { jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; jack_latency_range_t latency = { UINT32_MAX, 0 }; /* first setup all latency values of the ports. * this is based on the connections of the ports. */ list<jack_port_id_t>::iterator it; for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) { GetGraphManager()->RecalculateLatency(*it, mode); } if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) { GetGraphManager()->RecalculateLatency(*it, mode); } } if (!fLatency) { /* * default action is to assume all ports depend on each other. * then always take the maximum latency. */ if (mode == JackPlaybackLatency) { /* iterate over all OutputPorts, to find maximum playback latency */ for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if (port->GetFlags() & JackPortIsOutput) { jack_latency_range_t other_latency; port->GetLatencyRange(mode, &other_latency); if (other_latency.max > latency.max) { latency.max = other_latency.max; } if (other_latency.min < latency.min) { latency.min = other_latency.min; } } } if (latency.min == UINT32_MAX) { latency.min = 0; } /* now set the found latency on all input ports */ for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if (port->GetFlags() & JackPortIsInput) { port->SetLatencyRange(mode, &latency); } } } if (mode == JackCaptureLatency) { /* iterate over all InputPorts, to find maximum playback latency */ for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if (port->GetFlags() & JackPortIsInput) { jack_latency_range_t other_latency; port->GetLatencyRange(mode, &other_latency); if (other_latency.max > latency.max) { latency.max = other_latency.max; } if (other_latency.min < latency.min) { latency.min = other_latency.min; } } } if (latency.min == UINT32_MAX) { latency.min = 0; } /* now set the found latency on all output ports */ for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if (port->GetFlags() & JackPortIsOutput) { port->SetLatencyRange(mode, &latency); } } } return 0; } /* we have a latency callback setup by the client, * lets use it... */ fLatency(mode, fLatencyArg); return 0; }
int JackCoreMidiDriver::Attach() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; jack_port_id_t index; jack_nframes_t latency = buffer_size; jack_latency_range_t latency_range; const char *name; JackPort *port; JackCoreMidiPort *port_obj; latency_range.max = latency; latency_range.min = latency; // Physical inputs for (int i = 0; i < num_physical_inputs; i++) { port_obj = physical_input_ports[i]; name = port_obj->GetName(); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, buffer_size, &index) < 0) { jack_error("JackCoreMidiDriver::Attach - cannot register physical " "input port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(port_obj->GetAlias()); port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[i] = index; } // Virtual inputs for (int i = 0; i < num_virtual_inputs; i++) { port_obj = virtual_input_ports[i]; name = port_obj->GetName(); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, buffer_size, &index) < 0) { jack_error("JackCoreMidiDriver::Attach - cannot register virtual " "input port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(port_obj->GetAlias()); port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[num_physical_inputs + i] = index; } if (! fEngineControl->fSyncMode) { latency += buffer_size; latency_range.max = latency; latency_range.min = latency; } // Physical outputs for (int i = 0; i < num_physical_outputs; i++) { port_obj = physical_output_ports[i]; name = port_obj->GetName(); fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, buffer_size, &index); if (index == NO_PORT) { jack_error("JackCoreMidiDriver::Attach - cannot register physical " "output port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(port_obj->GetAlias()); port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[i] = index; } // Virtual outputs for (int i = 0; i < num_virtual_outputs; i++) { port_obj = virtual_output_ports[i]; name = port_obj->GetName(); fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, buffer_size, &index); if (index == NO_PORT) { jack_error("JackCoreMidiDriver::Attach - cannot register virtual " "output port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(port_obj->GetAlias()); port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[num_physical_outputs + i] = index; } return 0; }
int JackAlsaDriver::Attach() { JackPort* port; jack_port_id_t port_index; unsigned long port_flags = (unsigned long)CaptureDriverFlags; char name[REAL_JACK_PORT_NAME_SIZE]; char alias[REAL_JACK_PORT_NAME_SIZE]; assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver; if (alsa_driver->has_hw_monitoring) port_flags |= JackPortCanMonitor; // ALSA driver may have changed the values JackAudioDriver::SetBufferSize(alsa_driver->frames_per_cycle); JackAudioDriver::SetSampleRate(alsa_driver->frame_rate); jack_log("JackAlsaDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (int i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fCapturePortList[i] = port_index; jack_log("JackAlsaDriver::Attach fCapturePortList[i] %ld ", port_index); } port_flags = (unsigned long)PlaybackDriverFlags; for (int i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fPlaybackPortList[i] = port_index; jack_log("JackAlsaDriver::Attach fPlaybackPortList[i] %ld ", port_index); // Monitor ports if (fWithMonitorPorts) { jack_log("Create monitor port"); snprintf(name, sizeof(name), "%s:monitor_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("ALSA: cannot register monitor port for %s", name); } else { fMonitorPortList[i] = port_index; } } } UpdateLatencies(); if (alsa_driver->midi) { int err = (alsa_driver->midi->attach)(alsa_driver->midi); if (err) jack_error ("ALSA: cannot attach MIDI: %d", err); } return 0; }
int JackAlsaDriver::Attach() { JackPort* port; int port_index; unsigned long port_flags = (unsigned long)CaptureDriverFlags; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; jack_latency_range_t range; assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver; if (alsa_driver->has_hw_monitoring) port_flags |= JackPortCanMonitor; // ALSA driver may have changed the values JackAudioDriver::SetBufferSize(alsa_driver->frames_per_cycle); JackAudioDriver::SetSampleRate(alsa_driver->frame_rate); jack_log("JackAlsaDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (int i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); range.min = range.max = alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency; port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackAlsaDriver::Attach fCapturePortList[i] %ld ", port_index); } port_flags = (unsigned long)PlaybackDriverFlags; for (int i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); // Add one buffer more latency if "async" mode is used... range.min = range.max = (alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency; port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackAlsaDriver::Attach fPlaybackPortList[i] %ld ", port_index); // Monitor ports if (fWithMonitorPorts) { jack_log("Create monitor port"); snprintf(name, sizeof(name) - 1, "%s:monitor_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error ("ALSA: cannot register monitor port for %s", name); } else { port = fGraphManager->GetPort(port_index); range.min = range.max = alsa_driver->frames_per_cycle; port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } } if (alsa_driver->midi) { int err = (alsa_driver->midi->attach)(alsa_driver->midi); if (err) jack_error ("ALSA: cannot attach MIDI: %d", err); } return 0; }
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; } }