Execute program automatically on startup with sound output?

Hello,

I have a C++ program where I use the SDL2_Mixer module (which is based on Pulsesink, I think) to output audio. I want to run it on startup on the Jetson Nano, but it does not want to work out very well. I set my default audio output device to USB, volume etc. at startup automatically and have tried different ways to run the binary.

First, I included it in the Linux startup applications app. Then, I created a script in /etc/init.d which should run the binary and gave execute permissions. Also, I tried to do it with crontab. In all three ways, I didn’t hear any sound, even after I programmed in a delay so it can be made sure that everything is loaded and set when the binary runs.

Here’s my code:

#include <SDL2/SDL_mixer.h>
#include <SDL.h>
#include <string>
#include <thread>
#include <chrono>

const char waveFileName[40] = "audio/startup_sound.wav";
Mix_Chunk* sample;

int main() {
    if (Mix_Init(MIX_INIT_FLAC | MIX_INIT_MP3 | MIX_INIT_OGG) < 0) {
        exit(-1);
    }
    memset(sample, 0, sizeof(Mix_Chunk*) * 2);
    if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024) < 0) {
        exit(-1);
    }
    Mix_AllocateChannels(2);
    sample = Mix_LoadWAV(waveFileName);
    if (sample == NULL) {
        exit(-1);
    }

    Mix_Volume(0, MIX_MAX_VOLUME);
    Mix_PlayChannel(0, sample, 0);
    std::this_thread::sleep_for(std::chrono::seconds(13));

    Mix_FreeChunk(sample);
    Mix_CloseAudio();
    Mix_Quit();

    return 0;
}

I want to point out that when I run the program manually from the terminal, it works perfectly. Is there a way to execute it automatically on Jetson Nano’s startup so the audio output works? This is a very urgent problem, so any help would be appreciated!
Thanks!

What is the exact compile command used on your sample source code? If people are able to reproduce this it would be easier to answer. Also, is your compile native on the Jetson, or cross compile from a host PC?

I use Cmake for compiling native on the Jetson. I can’t name you a command because I use an IDE, but here’s the content of my CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
include(FindPkgConfig)

project(main)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -pthread")
set(source_dir "${PROJECT_SOURCE_DIR}/src/")

file(GLOB source_files "${source_dir}/*.cpp")

include_directories(${SDL2_INCLUDE_DIRS})
pkg_check_modules(SDL2_Mixer REQUIRED IMPORTED_TARGET SDL2_mixer)

add_executable(main ${source_files})
target_link_libraries(main ${SDL2_LIBRARIES})
target_link_libraries(main PkgConfig::SDL2_Mixer)

Could you print some message to make sure the APP have been run.

If by “app” you mean my program: Messages with cout I obviously can not see, so I tried a simple output to a file with ofstream, but it failed and didn’t give any message. So either the program is not running (which is very unlikely since I included it in the Linux startup applications GUI) or it executes before the whole environment is set up or something like that. Can you give hints about how to delay this automatic program execution?

Instead of a message (which @ShaneCCC suggested) perhaps you could create or touch a file to a temp location? An example might be to create a string via the “date” command, and then redirect that string to “/var/log/tmp.txt”. Seeing the file after boot would tell you for sure that the program attempted to run.

Note that when I used that CMakeLists.txt I had this output:

...
--   Found SDL2_mixer, version 2.0.2
CMake Error at CMakeLists.txt:16 (add_executable):
  add_executable called with incorrect number of arguments


CMake Error at CMakeLists.txt:17 (target_link_libraries):
  Cannot specify link libraries for target "main" which is not built by this
  project.


-- Configuring incomplete, errors occurred!

This is my CMakeOutput.log:
CMakeOutput.log (42.4 KB)

I cannot reproduce the program, and thus cannot personally check this out. I’d need to be able to build the executable to do any kind of testing.

Thanks for your assistance and efforts. Well, I don’t know what’s going on with your Cmake, but I use this CMakeLists.txt over and over on my Jetson Nano and it works perfectly. Perhaps you use an other Cmake or C++ version.

As for my autostart problem, I figured out an other kind of solution myself since none of the default ones have worked. To make sure my program only starts if everything is loaded and set up, I include the terminal to the autostart applications and then execute the binary in the ~/.bashrc file.

For others having a similar problem:

1. Start the terminal automatically at startup:

  • Search for “Startup applications” app (default app in Linux)
  • Click “Add”
  • Enter some title for the application, e.g. “Terminal”
  • As command, enter gnome-terminal
  • Click save and exit.

2. Add the executable to ~/.bashrc:

  • Open the file by $ gedit ~/.bashrc

  • At the end, append following lines:

    chmod u+x /path/to/executable
    /path/to/executable
    

On the next startup, the terminal should start automatically and execute the specified binary. I know this is kind of a temporary setup, but it’s a working one and it fits my needs since it’s helpful to see the terminal output while running the program.

You might be right, but I’m using the default version on a Jetson NX, release R32.4.3. This should be very close to your case. My versions:

  • cmake: 3.10.2
  • gcc and g++: 7.5.0

Are your versions different? The SDL components are where I suspect a difference since there is more than one release available and they have to be manually installed…this is where the two Jetsons will likely differ.

Since you worked around this it probably does not matter, but it would still be interesting to know the reason why my cmake of the app failed.

The error message says the problem lies in the number of arguments given to add_executable(). I’m pretty much clueless here, so I suggest you to have a look at this if you are still interested in solving the issue:

I pretty much followed this guide to set up my C++ environment in Linux and even copied large parts of the CMakeLists.txt file content he used, so I don’t think the problem lies within my code since it obviously works elsewhere. Anyway, thanks for your assistance and good luck!

Let me approach this another way: For the executable file, assmuning is named “program”, what do you see from:
ldd ./program
(you’ll have to cd to its location first, and if you use sudo with the program, then prefix ldd with sudo)

When I went to recreate the executable it was so I could see the dependencies, but if you run ldd on the same program from your side, then the output should be ok. In part this may answer what stage of boot is required. Also, make sure to describe if the program must run in a GUI environment.