#c #c #linux #alsa
#c #c #linux #alsa
Вопрос:
Я хочу программно воспроизводить произвольные звуки, используя aplay
Linux. Помимо воспроизведения я хочу использовать интерактивный режим для приостановки воспроизведения, который может быть достигнут нажатием клавиши пробела при запуске aplay
с терминала. Я думаю, этого можно достичь, отправив ' '
через канал процессу, который запускает aplay. Воспроизведение работает, но приостановка — нет.
Как мне ' '
правильно отправить сообщение через канал? Нужно ли мне делать что-то еще?
вот мой код
#ifndef APLAY_WRAPPER_H
#define APLAY_WRAPPER_H
#include <sys/types.h>
#include <csignal>
#include <iostream>
#include <stdio.h>
#include <string>
#include <unistd.h>
class APlayWrapper
{
private:
pid_t m_pid;
int pipefd[2]; // [0] is for reading and [1] is for writing
FILE* m_sub_process_input;
public:
APlayWrapper() : m_pid(0){};
~APlayWrapper(){};
void play(const std::stringamp; pathToFile)
{
pipe(pipefd); // create a pipe
m_pid = fork(); // spawn a child process
if (m_pid == 0)
{
execlp("/usr/bin/aplay", "/usr/bin/aplay", "-i", pathToFile, (char*)NULL);
}
m_sub_process_input = fdopen(pipefd[1], "w");
};
void stopPlayback()
{
if (isPlaying())
{
kill(m_pid, SIGTERM);
}
};
void pauseResumePlayback()
{
fwrite(" ", sizeof(char), 1, m_sub_process_input);
};
bool isPlaying()
{
if (0 == kill(m_pid, 0))
{
return true;
}
return false;
}
};
#endif
Комментарии:
1. Вероятно, вам нужно перевести
m_sub_process_input
поток в небуферизованный режим. Но использование потока кажется излишним. Вы могли бы просто использовать POSIX более низкого уровняwrite()
в файловом дескрипторе. Кроме того, в дочернем элементе вам необходимоdup2()
прочитать конец канала до стандартного дескриптора входного файла передexec
.2. Вы не можете отправлять «нажатия клавиш» через канал. Канал предназначен для отправки данных. Если вы хотите взаимодействовать с программой, которая использует терминал для «интерактивных» действий, вам следует использовать pty вместо канала. Если вы просто выполняете быстрый взлом, вы можете заставить свой образец работать, вызвав
fflush
afterfwrite
, но это будет ненадежно, поскольку это будет зависеть от того, как именно aplay считывает данные с терминала.3.
aplay
фактически считывает изstdin
.