Skip to content

Conversation

@twischer-adit
Copy link
Contributor

@twischer-adit twischer-adit commented May 22, 2019

JACK can be build for QNX and is working fine. I tested with different playback use cases so far.

I provided a makefile calling the WAF build tooling.

I used the following commands for testing

jackd -R -P 80 -d alsa -P pcmC0D0p -p 768 -n 3 -S
jack_simple_client

@7890 7890 added the QNX QNX Operating System label May 23, 2019
@twischer-adit twischer-adit force-pushed the adit_devel_SOPL-8091_jack_port_to_qnx branch from 02d4dd1 to 0c37f81 Compare September 9, 2019 09:10
@twischer-adit twischer-adit changed the title [PoC] JACK port for the QNX operating system JACK port for the QNX operating system Sep 9, 2019
@twischer-adit twischer-adit force-pushed the adit_devel_SOPL-8091_jack_port_to_qnx branch 2 times, most recently from d537c1e to 6f7e009 Compare October 1, 2019 12:04
@ghost ghost mentioned this pull request Feb 5, 2020
@twischer-adit twischer-adit force-pushed the adit_devel_SOPL-8091_jack_port_to_qnx branch 2 times, most recently from fd2fc43 to 3b263ff Compare May 12, 2020 09:33
@twischer-adit twischer-adit force-pushed the adit_devel_SOPL-8091_jack_port_to_qnx branch from 3b263ff to cdb3daf Compare June 5, 2020 12:24
@twischer-adit
Copy link
Contributor Author

The latest update introduces the following diff:

diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp
index a8962e1..6fcdf48 100644
--- a/linux/alsa/JackAlsaDriver.cpp
+++ b/linux/alsa/JackAlsaDriver.cpp
@@ -205,7 +205,6 @@ int JackAlsaDriver::Detach()
 }
 
 #ifndef __QNXNTO__
-/* del6kor : ToDo : why is strndup not avaiable despite the indludes*/
 extern "C" char* get_control_device_name(const char * device_name)
 {
     char * ctl_name;
@@ -238,7 +237,6 @@ extern "C" char* get_control_device_name(const char * device_name)
 #endif
 
 #ifndef __QNXNTO__
-/* del6kor : ToDo : is this needed ? */
 static int card_to_num(const char* device)
 {
     int err;
@@ -969,8 +967,13 @@ void SetTime(jack_time_t time)
 int Restart()
 {
     int res;
-    if ((res = g_alsa_driver->Stop()) == 0) {
-        res = g_alsa_driver->Start();
+    if ((res = g_alsa_driver->Stop()) != 0) {
+        jack_error("restart: stop driver failed");
+        return res;
+    }
+    if ((res = g_alsa_driver->Start()) != 0) {
+        jack_error("restart: start driver failed");
+        return res;
     }
     return res;
 }
diff --git a/linux/alsa/alsa_driver.c b/linux/alsa/alsa_driver.c
index 72f97a6..1e7eeb4 100644
--- a/linux/alsa/alsa_driver.c
+++ b/linux/alsa/alsa_driver.c
@@ -411,7 +411,6 @@ alsa_driver_allocate_buffer(alsa_driver_t *driver, int frames, int channels, boo
 	}
 
 	jack_error ("ALSA: could not allocate audio buffer");
-	alsa_driver_delete(driver);
 	return -1;
 }
 
@@ -1401,6 +1400,7 @@ alsa_driver_start (alsa_driver_t *driver)
 
 		if (alsa_driver_get_channel_addresses (driver,
 					0, &pavail, 0, &poffset)) {
+			jack_error("silence failed, get channel addresses");
 			return -1;
 		}
 
@@ -1481,7 +1481,8 @@ alsa_driver_stop (alsa_driver_t *driver)
 
 	if (driver->playback_handle) {
 #ifdef __QNXNTO__
-		err = snd_pcm_plugin_flush(driver->playback_handle, SND_PCM_CHANNEL_PLAYBACK);
+		/* In case of playback: Drain discards the frames */
+		err = snd_pcm_plugin_playback_drain(driver->playback_handle);
 #else
 		err = snd_pcm_drop (driver->playback_handle);
 #endif
@@ -1496,6 +1497,7 @@ alsa_driver_stop (alsa_driver_t *driver)
 	    || driver->capture_and_playback_not_synced) {
 		if (driver->capture_handle) {
 #ifdef __QNXNTO__
+			/* In case of capture: Flush discards the frames */
 			err = snd_pcm_plugin_flush(driver->capture_handle, SND_PCM_CHANNEL_CAPTURE);
 #else
 			err = snd_pcm_drop (driver->capture_handle);
@@ -1556,7 +1558,6 @@ alsa_driver_get_status (alsa_driver_t *driver)
 	}
 
 #ifdef __QNXNTO__
-	/* ToDo : ldevi : Can be moved a different func? s*/
 	memset (&status, 0, sizeof (status));
 	status.channel = driver->capture_handle ? SND_PCM_CHANNEL_CAPTURE :
 	                                          SND_PCM_CHANNEL_PLAYBACK;
@@ -1598,7 +1599,7 @@ alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
 	    && driver->process_count > XRUN_REPORT_DELAY) {
 		driver->xrun_count++;
 #ifdef __QNXNTO__
-		/* ldevi : ToDo Check if there is a replacement*/
+		/* Timestamp api's are not available as per QNX Documentation */
 		*delayed_usecs = 0;
 #else
 		struct timeval now, diff, tstamp;
@@ -1625,6 +1626,7 @@ alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
 	}
 
 	if (alsa_driver_restart (driver)) {
+		jack_error("xrun recovery failed to restart driver");
 		return -1;
 	}
 	return 0;
@@ -1663,22 +1665,7 @@ alsa_driver_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int s
 static snd_pcm_sframes_t
 alsa_driver_avail(alsa_driver_t *driver, snd_pcm_t *pcm, bool is_capture)
 {
-	int err;
-	snd_pcm_channel_status_t status = {0, };
-
-    status.channel = is_capture;
-    err = snd_pcm_plugin_status (pcm, &status);
-	if (err < 0)
-		return err;
-
-	switch (status.status) {
-	case SND_PCM_STATUS_UNDERRUN:
-	case SND_PCM_STATUS_OVERRUN:
-	case SND_PCM_STATUS_UNSECURE:
-	case SND_PCM_STATUS_CHANGE:
-		return -EPIPE;
-	}
-
+	/* QNX guarantees that after poll() event at least one perido is available */
 	return driver->frames_per_cycle;
 }
 #else
@@ -2485,23 +2472,27 @@ alsa_driver_open (alsa_driver_t *driver, bool is_capture)
 
 		case EINVAL:
 			jack_error ("the state of handle or the mode is invalid "
-				"or invalid state change occured \"%s\" for playback",
-				is_capture ? driver->alsa_name_capture : driver->alsa_name_playback);
+				"or invalid state change occured \"%s\" for %s",
+				is_capture ? driver->alsa_name_capture : driver->alsa_name_playback,
+				is_capture ? "capture" : "playback");
 			break;
 
 		case ENOENT:
-			jack_error ("device \"%s\"  does not exist for playback",
-				is_capture ? driver->alsa_name_capture : driver->alsa_name_playback);
+			jack_error ("device \"%s\"  does not exist for %s",
+				is_capture ? driver->alsa_name_capture : driver->alsa_name_playback,
+				is_capture ? "capture" : "playback");
 			break;
 
 		case ENOMEM:
-			jack_error ("Not enough memory available for allocation for \"%s\" for playback",
-				is_capture ? driver->alsa_name_capture : driver->alsa_name_playback);
+			jack_error ("Not enough memory available for allocation for \"%s\" for %s",
+				is_capture ? driver->alsa_name_capture : driver->alsa_name_playback,
+				is_capture ? "capture" : "playback");
 			break;
 
 		case SND_ERROR_INCOMPATIBLE_VERSION:
-			jack_error ("Version mismatch \"%s\" for playback",
-				is_capture ? driver->alsa_name_capture : driver->alsa_name_playback);
+			jack_error ("Version mismatch \"%s\" for %s",
+				is_capture ? driver->alsa_name_capture : driver->alsa_name_playback,
+				is_capture ? "capture" : "playback");
 			break;
 		}
 		alsa_driver_delete (driver);

It mainly removes TODO comments and solves some minor QNX specific issues.

@falkTX
Copy link
Member

falkTX commented Jun 10, 2020

Merging this is tricky, because I have no device with such architecture.
Is there any way we can add a CI check for QNX?
(the osx CI build is broken at the moment, I know, will fix sometime soon. just takes ages to verify any possible fix)

@twischer-adit
Copy link
Contributor Author

Hello @falkTX,

I have not yet touched CI. Are you aware of any good introduction? What would we need to provide to get it build for QNX? I expect the build is running on Linux with some cross compile environment, right?

@falkTX
Copy link
Member

falkTX commented Jun 11, 2020

Mostly all it needs is a script or set of instructions to automatically build what is needed, even better if it can be tested afterwards.
If you can tell me how you cross-compile, I might be able to add it in.

@twischer-adit
Copy link
Contributor Author

Hi @falkTX,
I have done a short research. The instructions to install the QNX compiler and the headers can be found in [1].

But I am not sure if QNX would provide a license for free for this purpose. You can get a
30-day evaluation license for free [2]. Licenses for education are also provided for free [3]. There it is mentioned that such licenses are for research purpose. Therefore may be QNX would offer such a license for this project.
Would you like to raise this question to QNX as the maintainer of this project?

[1] http://www.qnx.com/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.momentics_installation_guide%2Flinux_hosts.html&anchor=Install
[2] http://www.qnx.com/products/evaluation/
[3] http://www.qnx.com/company/education/

@falkTX
Copy link
Member

falkTX commented Jun 17, 2020

oh, so QNX is not an open system?
nevermind then, I have no interest on such things.

you can leave the PR open so others can check the status and know that this exists.
but I won't be the one merging it.

Timo Wischer and others added 12 commits June 25, 2020 16:17
Change-Id: Ia6aee61aa7059a70d2014f7de66a41cbaca8c7ed
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: I1cab18816980f704b6ae73a37960c1421e46ed9b
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: Ic0b9c377e111cb59ed4859819b810842347e8525
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: I69bc2a73849431925c14d865bc970e2cbfa2d843
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
because it is not available in QNX

Change-Id: I94a7586c148aa4f9b6cd6fef98a8637e7fea717c
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: I40287828155d7b7530d8760724b3fb3b06ae15b7
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: I7ea831b96cb774fc69b7934c65797a51e9b9ec6a
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: I92760ed539b475e210bc877b335afdbb4a982a04
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: Id1dda94d4621a8e77c76c2cd15f08e26a31b87e5
Signed-off-by: Laxmi Devi <Laxmi.Devi@in.bosch.com>
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
shave off a few usec from processing time

Change-Id: I052d168b11caa54d881d651c32822d6db33383b8
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
(cherry picked from commit 138925dfd5c45c99d7978ba39f99d9d0fc349727)
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: I9ee88d6b2531622c8d46f69872d30750168c4e4a
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
vsnprintf implementation on QNX can not handle NULL string parameter and
will interrupt, This is a workaround for the same

Change-Id: I18c57ec4b596336cea6f3061caf49c0b33afe198
Signed-off-by: Laxmi Devi <Laxmi.Devi@in.bosch.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

QNX QNX Operating System

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants