start/stop for audio player
This commit is contained in:
parent
3bb280cda2
commit
484db9bdfa
|
@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.16)
|
||||||
project("pyaudioplayeralsa")
|
project("pyaudioplayeralsa")
|
||||||
|
|
||||||
add_executable(play main.cpp src/WavFile.cpp)
|
add_executable(play main.cpp src/WavFile.cpp)
|
||||||
target_link_libraries(play -lasound)
|
target_link_libraries(play -lasound -pthread)
|
|
@ -28,13 +28,38 @@
|
||||||
|
|
||||||
#include "src/WavFile.h"
|
#include "src/WavFile.h"
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#define PCM_DEVICE "default"
|
#define PCM_DEVICE "default"
|
||||||
|
|
||||||
|
std::deque<std::string> queue;
|
||||||
|
std::mutex queueMutex;
|
||||||
|
|
||||||
|
static std::string getInput()
|
||||||
|
{
|
||||||
|
|
||||||
|
std::cout << "starting input thread" << std::endl;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
std::getline(std::cin, result);
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(queueMutex);
|
||||||
|
std::cout << "adding to queue" << std::endl;
|
||||||
|
queue.push_back(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
std::ifstream wavFileStream("test.wav", std::ios::binary);
|
std::ifstream wavFileStream("test.wav", std::ios::binary);
|
||||||
WavFile wav(wavFileStream);
|
WavFile wav(wavFileStream);
|
||||||
wavFileStream.close();
|
wavFileStream.close();
|
||||||
|
std::cout << "Wav samples " << wav.size() << std::endl;
|
||||||
|
|
||||||
unsigned int pcm, tmp, dir;
|
unsigned int pcm, tmp, dir;
|
||||||
snd_pcm_t *pcm_handle;
|
snd_pcm_t *pcm_handle;
|
||||||
|
@ -66,6 +91,8 @@ int main(int argc, char **argv)
|
||||||
if (pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, wav.channels()) < 0)
|
if (pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, wav.channels()) < 0)
|
||||||
printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));
|
printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));
|
||||||
|
|
||||||
|
snd_pcm_hw_params_set_buffer_size(pcm_handle, params, 2 * 2048);
|
||||||
|
|
||||||
unsigned int rate = wav.sampleRate();
|
unsigned int rate = wav.sampleRate();
|
||||||
if (pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0) < 0)
|
if (pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0) < 0)
|
||||||
printf("ERROR: Can't set rate. %s\n", snd_strerror(pcm));
|
printf("ERROR: Can't set rate. %s\n", snd_strerror(pcm));
|
||||||
|
@ -80,6 +107,7 @@ int main(int argc, char **argv)
|
||||||
printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));
|
printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));
|
||||||
|
|
||||||
snd_pcm_hw_params_get_channels(params, &tmp);
|
snd_pcm_hw_params_get_channels(params, &tmp);
|
||||||
|
|
||||||
printf("channels: %i ", tmp);
|
printf("channels: %i ", tmp);
|
||||||
|
|
||||||
if (tmp == 1)
|
if (tmp == 1)
|
||||||
|
@ -95,26 +123,52 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
buff_size = frames * wav.channels() * 2 /* 2 -> sample size */;
|
buff_size = frames * wav.channels() * 2 /* 2 -> sample size */;
|
||||||
buff = (char *)malloc(buff_size);
|
buff = (char *)malloc(buff_size);
|
||||||
|
std::cout << "Buffer size " << buff_size << " frames " << frames << std::endl;
|
||||||
|
|
||||||
snd_pcm_hw_params_get_period_time(params, &tmp, NULL);
|
snd_pcm_hw_params_get_period_time(params, &tmp, NULL);
|
||||||
|
|
||||||
|
std::thread inputThread(getInput);
|
||||||
|
bool playing = true;
|
||||||
|
|
||||||
size_t wavFilePosition = 0;
|
size_t wavFilePosition = 0;
|
||||||
while (wavFilePosition < wav.size())
|
while (wavFilePosition < wav.size())
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(queueMutex);
|
||||||
|
if (queue.size() > 0)
|
||||||
|
{
|
||||||
|
queue.pop_back();
|
||||||
|
std::cout << "Toggling" << std::endl;
|
||||||
|
//snd_pcm_drain(pcm_handle);
|
||||||
|
std::cout << "Done" << std::endl;
|
||||||
|
playing = !playing;
|
||||||
|
if (playing)
|
||||||
|
{
|
||||||
|
std::cout << "continuing at " << wavFilePosition << std::endl;
|
||||||
|
snd_pcm_pause(pcm_handle, 0);
|
||||||
|
//snd_pcm_prepare(pcm_handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
snd_pcm_pause(pcm_handle, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!playing)
|
||||||
|
continue;
|
||||||
size_t dataToWrite = std::min(size_t(buff_size), wav.size() - wavFilePosition);
|
size_t dataToWrite = std::min(size_t(buff_size), wav.size() - wavFilePosition);
|
||||||
int framesToWrite = dataToWrite / wav.channels() / 2;
|
int framesToWrite = dataToWrite / wav.channels() / 2;
|
||||||
if (pcm = snd_pcm_writei(pcm_handle, wav[wavFilePosition], framesToWrite) == -EPIPE)
|
if (pcm = snd_pcm_writei(pcm_handle, wav[wavFilePosition], framesToWrite) == -EPIPE)
|
||||||
{
|
{
|
||||||
printf("XRUN.\n");
|
std::cout << "XRUN at wav position " << wavFilePosition << std::endl;
|
||||||
snd_pcm_prepare(pcm_handle);
|
snd_pcm_prepare(pcm_handle);
|
||||||
}
|
}
|
||||||
else if (pcm < 0)
|
else if (pcm < 0)
|
||||||
{
|
|
||||||
printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(pcm));
|
printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(pcm));
|
||||||
}
|
|
||||||
wavFilePosition += dataToWrite;
|
wavFilePosition += dataToWrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "done filling buffer" << std::endl;
|
||||||
snd_pcm_drain(pcm_handle);
|
snd_pcm_drain(pcm_handle);
|
||||||
snd_pcm_close(pcm_handle);
|
snd_pcm_close(pcm_handle);
|
||||||
free(buff);
|
free(buff);
|
||||||
|
|
Loading…
Reference in New Issue