Initial commit.

This commit is contained in:
jmsgrogan 2020-05-02 08:31:03 +01:00
commit 59c6161fdb
134 changed files with 4751 additions and 0 deletions

71
src/audio/AudioDevice.cpp Normal file
View file

@ -0,0 +1,71 @@
#include "AudioDevice.h"
AudioDevice::AudioDevice()
: mName("plughw:1,0"),
mSampleRate(44100),
mNumChannels(2),
mPeriod(2),
mBufferSize()
{
}
AudioDevice::~AudioDevice()
{
}
std::shared_ptr<AudioDevice> AudioDevice::Create()
{
return std::make_shared<AudioDevice>();
}
void AudioDevice::SetNumChannels(unsigned numChannels)
{
mNumChannels = numChannels;
}
void AudioDevice::SetPeriod(unsigned period)
{
mPeriod = period;
}
void AudioDevice::SetBufferSize(std::size_t bufferSize)
{
mBufferSize = bufferSize;
}
unsigned AudioDevice::GetNumChannels()
{
return mNumChannels;
}
unsigned AudioDevice::GetPeriod()
{
return mPeriod;
}
std::size_t AudioDevice::GetBufferSize()
{
return mBufferSize;
}
void AudioDevice::SetSampleRate(unsigned rate)
{
mSampleRate = rate;
}
unsigned AudioDevice::GetSampleRate()
{
return mSampleRate;
}
void AudioDevice::SetName(const std::string& name)
{
mName = name;
}
std::string AudioDevice::GetName()
{
return mName;
}

46
src/audio/AudioDevice.h Normal file
View file

@ -0,0 +1,46 @@
#pragma once
#include <memory>
#include <string>
class AudioDevice
{
private:
std::string mName;
unsigned mSampleRate;
unsigned mNumChannels;
unsigned mPeriod;
std::size_t mBufferSize;
public:
AudioDevice();
~AudioDevice();
void SetSampleRate(unsigned rate);
unsigned GetSampleRate();
void SetName(const std::string& name);
void SetNumChannels(unsigned numChannels);
void SetPeriod(unsigned period);
void SetBufferSize(std::size_t bufferSize);
unsigned GetNumChannels();
unsigned GetPeriod();
std::size_t GetBufferSize();
std::string GetName();
static std::shared_ptr<AudioDevice> Create();
};
using AudioDevicePtr = std::shared_ptr<AudioDevice>;

View file

@ -0,0 +1,33 @@
#include "AudioManager.h"
AudioManager::AudioManager()
: mAudioDevices(),
mAudioInterface()
{
mAudioInterface = AlsaInterface::Create();
}
AudioManager::~AudioManager()
{
}
std::shared_ptr<AudioManager> AudioManager::Create()
{
return std::make_shared<AudioManager>();
}
void AudioManager::AddAudioDevice(AudioDevicePtr device)
{
mAudioDevices.push_back(device);
}
AlsaInterfacePtr AudioManager::GetAudioInterface()
{
return mAudioInterface;
}
std::vector<AudioDevicePtr> AudioManager::GetAudioDevices()
{
return mAudioDevices;
}

32
src/audio/AudioManager.h Normal file
View file

@ -0,0 +1,32 @@
#pragma once
#include <memory>
#include <vector>
#include "AlsaInterface.h"
#include "AudioDevice.h"
class AudioManager
{
private:
std::vector<AudioDevicePtr> mAudioDevices;
AlsaInterfacePtr mAudioInterface;
public:
AudioManager();
~AudioManager();
static std::shared_ptr<AudioManager> Create();
void AddAudioDevice(AudioDevicePtr device);
std::vector<AudioDevicePtr> GetAudioDevices();
AlsaInterfacePtr GetAudioInterface();
};
using AudioManagerPtr = std::shared_ptr<AudioManager>;

13
src/audio/CMakeLists.txt Normal file
View file

@ -0,0 +1,13 @@
list(APPEND audio_LIB_INCLUDES
AudioDevice.cpp
AudioManager.cpp
audio_interfaces/AlsaInterface.cpp)
add_library(audio SHARED ${audio_LIB_INCLUDES})
target_include_directories(audio PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/audio_interfaces"
)
target_link_libraries(audio PUBLIC asound)

View file

@ -0,0 +1,141 @@
#include "AlsaInterface.h"
#include <iostream>
AlsaInterface::AlsaInterface()
:mHandle(),
mHardwareParams(),
mPeriodSize(8192)
{
}
AlsaInterface::~AlsaInterface()
{
}
std::shared_ptr<AlsaInterface> AlsaInterface::Create()
{
return std::make_shared<AlsaInterface>();
}
void AlsaInterface::OpenDevice(AudioDevicePtr device)
{
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
if (snd_pcm_open(&mHandle, device->GetName().c_str(), stream, 0) < 0)
{
std::cerr << "Error opening PCM device: " << device->GetName() << std::endl;
return;
}
snd_pcm_hw_params_alloca(&mHardwareParams);
if (snd_pcm_hw_params_any(mHandle, mHardwareParams) < 0)
{
std::cerr << "Can not configure this PCM device.\n" << std::endl;
return;
}
SetAccessType(device);
SetSampleFormat(device);
SetSampleRate(device);
SetPeriod(device);
SetBufferSize(device);
SetChannelNumber(device);
/* Apply HW parameter settings to */
/* PCM device and prepare device */
if (snd_pcm_hw_params(mHandle, mHardwareParams) < 0) {
std::cerr << "Error setting HW params." << std::endl;
return;
}
}
void AlsaInterface::SetAccessType(AudioDevicePtr device)
{
if (snd_pcm_hw_params_set_access(mHandle, mHardwareParams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
std::cerr << "Error setting device access." << std::endl;
return;
}
}
void AlsaInterface::SetSampleFormat(AudioDevicePtr device)
{
/* Set sample format */
if (snd_pcm_hw_params_set_format(mHandle, mHardwareParams, SND_PCM_FORMAT_S16_LE) < 0) {
std::cerr << "Error setting format. " << std::endl;
return;
}
}
void AlsaInterface::SetSampleRate(AudioDevicePtr device)
{
unsigned rate = device->GetSampleRate();
unsigned exact_rate = rate;
if (snd_pcm_hw_params_set_rate_near(mHandle, mHardwareParams, &exact_rate, 0) < 0)
{
std::cerr << "Error setting rate. " << std::endl;
return;
}
if (rate != exact_rate) {
std::cerr << "The rate is not supported by your hardware." << std::endl;
}
}
void AlsaInterface::SetPeriod(AudioDevicePtr device)
{
/* Set number of periods. Periods used to be called fragments. */
if (snd_pcm_hw_params_set_periods(mHandle, mHardwareParams, device->GetPeriod(), 0) < 0)
{
std::cerr << "Error setting periods. " << std::endl;
return;
}
}
void AlsaInterface::SetBufferSize(AudioDevicePtr device)
{
snd_pcm_uframes_t periodsize = 8192; /* Periodsize (bytes) */
int periods = static_cast<int>(device->GetPeriod());
/* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame) */
if (snd_pcm_hw_params_set_buffer_size(mHandle, mHardwareParams, (mPeriodSize * periods)>>2) < 0)
{
std::cerr << "Error setting buffersize. " << std::endl;
return;
}
}
void AlsaInterface::SetChannelNumber(AudioDevicePtr device)
{
/* Set number of channels */
if (snd_pcm_hw_params_set_channels(mHandle, mHardwareParams, device->GetNumChannels()) < 0)
{
std::cout << "Error setting channels" << std::endl;
return;
}
}
void AlsaInterface::Play(AudioDevicePtr device)
{
int num_frames = 10;
unsigned char *data = (unsigned char *)malloc(mPeriodSize);
int frames = mPeriodSize >> 2;
for(int l1 = 0; l1 < 100; l1++)
{
for(int l2 = 0; l2 < num_frames; l2++)
{
short s1 = (l2 % 128) * 100 - 5000;
short s2 = (l2 % 256) * 100 - 5000;
data[4*l2] = (unsigned char)s1;
data[4*l2+1] = s1 >> 8;
data[4*l2+2] = (unsigned char)s2;
data[4*l2+3] = s2 >> 8;
}
while ((snd_pcm_writei(mHandle, data, frames)) < 0)
{
snd_pcm_prepare(mHandle);
fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>\n");
}
}
}

View file

@ -0,0 +1,39 @@
#pragma once
#include <memory>
#include <alsa/asoundlib.h>
#include "AudioDevice.h"
class AlsaInterface
{
snd_pcm_t* mHandle;
snd_pcm_hw_params_t* mHardwareParams;
snd_pcm_uframes_t mPeriodSize;
public:
AlsaInterface();
~AlsaInterface();
static std::shared_ptr<AlsaInterface> Create();
void OpenDevice(AudioDevicePtr device);
void SetAccessType(AudioDevicePtr device);
void SetSampleFormat(AudioDevicePtr device);
void SetSampleRate(AudioDevicePtr device);
void SetPeriod(AudioDevicePtr device);
void SetBufferSize(AudioDevicePtr device);
void SetChannelNumber(AudioDevicePtr device);
void Play(AudioDevicePtr device);
};
using AlsaInterfacePtr = std::shared_ptr<AlsaInterface>;