示例#1
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;
}
示例#2
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;
}
示例#3
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;
}