Esempio n. 1
0
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;
        }
    }
}
Esempio n. 2
0
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;
    }
}
Esempio n. 3
0
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;
        }
    }
}
Esempio n. 4
0
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);
        }
    }
}
Esempio n. 5
0
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;
    }
}
Esempio n. 6
0
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;
}
Esempio n. 7
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);
    }
}
Esempio n. 8
0
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);
        }
    }
}
Esempio n. 9
0
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;
}
Esempio n. 10
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
int JackClient::PortIsMine(jack_port_id_t port_index)
{
    JackPort* port = GetGraphManager()->GetPort(port_index);
    return GetClientControl()->fRefNum == port->GetRefNum();
}
Esempio n. 18
0
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;
}
Esempio n. 19
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;
}
Esempio n. 20
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;
}
Esempio n. 21
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;
}
Esempio n. 22
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;
    }
}