mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-18 21:41:21 +00:00
Added back the original ALSA output plugin. PulseAudio is turning out to be a pain to implement, and has latency issues. Let's see if we can clean up and fix the original ASIO implementation.
This commit is contained in:
parent
2dc8fef1e2
commit
f0bca767e2
357
src/contrib/alsaout/AlsaOut.cpp
Executable file
357
src/contrib/alsaout/AlsaOut.cpp
Executable file
@ -0,0 +1,357 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2007, Daniel nnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include "AlsaOut.h"
|
||||
|
||||
AlsaOut::AlsaOut()
|
||||
:waveHandle(NULL)
|
||||
,maxBuffers(32)
|
||||
,currentVolume(1.0)
|
||||
,addToRemovedBuffers(false)
|
||||
,device("default")
|
||||
,output(NULL)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "AlsaOut::AlsaOut() called" << std::endl;
|
||||
#endif
|
||||
int err;
|
||||
if ((err = snd_pcm_open (&waveHandle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
|
||||
std::cerr << "AlsaOut: cannot open audio device 'default' :" << snd_strerror(err) << std::endl;
|
||||
return;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: audio device opened" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
|
||||
std::cerr << "AlsaOut: cannot allocate hardware parameter structure " << snd_strerror(err) << std::endl;
|
||||
exit (1);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: audio interface prepared for use" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err = snd_pcm_hw_params_any (waveHandle, hw_params)) < 0) {
|
||||
std::cerr << "AlsaOut: cannot initialize hardware parameter structure " << snd_strerror(err) << std::endl;
|
||||
exit (1);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: audio interface prepared for use" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err = snd_pcm_hw_params_set_access (waveHandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
|
||||
std::cerr << "AlsaOut: cannot set access type " << snd_strerror(err) << std::endl;
|
||||
exit (1);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: access type set" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err = snd_pcm_hw_params_set_format (waveHandle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
|
||||
std::cerr << "AlsaOut: cannot set sample format " << snd_strerror(err) << std::endl;
|
||||
exit (1);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: sample format set" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err = snd_pcm_hw_params_set_rate_resample (waveHandle, hw_params, 44100)) < 0) {
|
||||
std::cerr << "AlsaOut: cannot set sample rate " << snd_strerror(err) << std::endl;
|
||||
exit (1);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: sample rate set" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err = snd_pcm_hw_params_set_channels (waveHandle, hw_params, 2)) < 0) {
|
||||
std::cerr << "AlsaOut: cannot set channel count " << snd_strerror(err) << std::endl;
|
||||
exit (1);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: channel count set" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err = snd_pcm_hw_params (waveHandle, hw_params)) < 0) {
|
||||
std::cerr << "AlsaOut: cannot set parameters " << snd_strerror(err) << std::endl;
|
||||
exit (1);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: parameters set" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
snd_pcm_hw_params_free (hw_params);
|
||||
|
||||
if ((err = snd_pcm_prepare (waveHandle)) < 0) {
|
||||
std::cerr << "cannot prepare audio interface for use " << snd_strerror(err) << std::endl;
|
||||
exit (1);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "AlsaOut: audio interface prepared for use" << std::endl;
|
||||
}
|
||||
std::cerr << "waveHandle: " << waveHandle << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
AlsaOut::~AlsaOut(){
|
||||
this->ClearBuffers();
|
||||
|
||||
if(this->waveHandle!=NULL){
|
||||
snd_pcm_close(this->waveHandle);
|
||||
this->waveHandle = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
snd_pcm_t* AlsaOut::getWaveHandle() {
|
||||
return this->waveHandle;
|
||||
}
|
||||
|
||||
void AlsaOut::Destroy(){
|
||||
delete this;
|
||||
}
|
||||
/*
|
||||
void WaveOut::Initialize(IPlayer *player){
|
||||
this->player = player;
|
||||
}
|
||||
*/
|
||||
void AlsaOut::Pause(){
|
||||
snd_pcm_pause(this->waveHandle, 1);
|
||||
}
|
||||
|
||||
void AlsaOut::Resume(){
|
||||
snd_pcm_pause(this->waveHandle, 0);
|
||||
}
|
||||
|
||||
void AlsaOut::SetVolume(double volume){
|
||||
/*if(this->waveHandle){
|
||||
DWORD newVolume = (DWORD)(volume*65535.0);
|
||||
newVolume += newVolume*65536;
|
||||
|
||||
waveOutSetVolume(this->waveHandle,newVolume);
|
||||
}
|
||||
this->currentVolume = volume;*/ //TODO: Write alsa SetVolume() function
|
||||
}
|
||||
|
||||
void AlsaOut::ClearBuffers(){
|
||||
snd_pcm_drop(this->waveHandle);
|
||||
snd_pcm_reset(this->waveHandle);
|
||||
}
|
||||
|
||||
void AlsaOut::RemoveBuffer(AlsaOutBuffer *buffer){
|
||||
BufferList clearBuffers;
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
bool found(false);
|
||||
for(BufferList::iterator buf=this->buffers.begin();buf!=this->buffers.end() && !found;){
|
||||
if(buf->get()==buffer){
|
||||
// if( !(*buf)->ReadyToRelease() ){
|
||||
this->removedBuffers.push_back(*buf);
|
||||
// }
|
||||
clearBuffers.push_back(*buf);
|
||||
buf=this->buffers.erase(buf);
|
||||
found=true;
|
||||
}else{
|
||||
++buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AlsaOut::ReleaseBuffers(){
|
||||
BufferList clearBuffers;
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
for(BufferList::iterator buf=this->removedBuffers.begin();buf!=this->removedBuffers.end();){
|
||||
clearBuffers.push_back(*buf);
|
||||
buf = this->removedBuffers.erase(buf);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool AlsaOut::PlayBuffer(IBuffer *buffer,IPlayer *player){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "AlsaOut::PlayBuffer()" << std::endl;
|
||||
std::cerr << "Buffer: " << buffer << std::endl;
|
||||
#endif
|
||||
size_t bufferSize = 0;
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
bufferSize = this->buffers.size();
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "buffer size: " << bufferSize << std::endl;
|
||||
#endif
|
||||
|
||||
// if the format should change, wait for all buffers to be released
|
||||
if(bufferSize>0 && (this->currentChannels!=buffer->Channels() || this->currentSampleRate!=buffer->SampleRate())){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "format changed" << std::endl;
|
||||
#endif
|
||||
// Format has changed
|
||||
// this->player->Notify()
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(bufferSize<this->maxBuffers){
|
||||
// Start by checking the format
|
||||
this->SetFormat(buffer);
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "format set" << std::endl;
|
||||
#endif
|
||||
|
||||
// Add to the waveout internal buffers
|
||||
AlsaOutBufferPtr alsaBuffer(new AlsaOutBuffer(this,buffer,player));
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "alsaBuffer created" << std::endl;
|
||||
#endif
|
||||
|
||||
// Header should now be prepared, lets add to waveout
|
||||
if( alsaBuffer->AddToOutput() ){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "added to internal buffer" << std::endl;
|
||||
#endif
|
||||
// Add to the buffer list
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
this->buffers.push_back(alsaBuffer);
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "added to buffer list" << std::endl;
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "buffer size too big" << std::endl;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AlsaOut::SetFormat(IBuffer *buffer){
|
||||
if(this->currentChannels!=buffer->Channels() || this->currentSampleRate!=buffer->SampleRate() ||this->waveHandle==NULL){
|
||||
this->currentChannels = buffer->Channels();
|
||||
this->currentSampleRate = buffer->SampleRate();
|
||||
|
||||
// Close old waveout
|
||||
if(this->waveHandle!=NULL){
|
||||
snd_pcm_close(this->waveHandle);
|
||||
this->waveHandle = NULL;
|
||||
}
|
||||
/*
|
||||
// Create a new waveFormat
|
||||
ZeroMemory(&this->waveFormat, sizeof(this->waveFormat));
|
||||
DWORD speakerconfig;
|
||||
|
||||
// Set speaker configuration
|
||||
switch(buffer->Channels()){
|
||||
case 1:
|
||||
speakerconfig = KSAUDIO_SPEAKER_MONO;
|
||||
break;
|
||||
case 2:
|
||||
speakerconfig = KSAUDIO_SPEAKER_STEREO;
|
||||
break;
|
||||
case 4:
|
||||
speakerconfig = KSAUDIO_SPEAKER_QUAD;
|
||||
break;
|
||||
case 5:
|
||||
speakerconfig = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT);
|
||||
break;
|
||||
case 6:
|
||||
speakerconfig = KSAUDIO_SPEAKER_5POINT1;
|
||||
break;
|
||||
default:
|
||||
speakerconfig = 0;
|
||||
}
|
||||
|
||||
this->waveFormat.Format.cbSize = 22;
|
||||
this->waveFormat.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
this->waveFormat.Format.nChannels = (WORD)buffer->Channels();
|
||||
this->waveFormat.Format.nSamplesPerSec = (DWORD)buffer->SampleRate();
|
||||
this->waveFormat.Format.wBitsPerSample = 32;
|
||||
this->waveFormat.Format.nBlockAlign = (this->waveFormat.Format.wBitsPerSample/8) * this->waveFormat.Format.nChannels;
|
||||
this->waveFormat.Format.nAvgBytesPerSec = ((this->waveFormat.Format.wBitsPerSample/8) * this->waveFormat.Format.nChannels) * this->waveFormat.Format.nSamplesPerSec; //Compute using nBlkAlign * nSamp/Sec
|
||||
|
||||
// clangen: wValidBitsPerSample/wReserved/wSamplesPerBlock are a union,
|
||||
// so don't set wReserved or wSamplesPerBlock to 0 after assigning
|
||||
// wValidBitsPerSample. (Vista bug)
|
||||
this->waveFormat.Samples.wValidBitsPerSample = 32;
|
||||
this->waveFormat.dwChannelMask = speakerconfig;
|
||||
this->waveFormat.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
|
||||
*/
|
||||
this->waveFormat = SND_PCM_FORMAT_FLOAT_LE;
|
||||
this->waveAccess = SND_PCM_ACCESS_RW_INTERLEAVED;
|
||||
|
||||
int err;
|
||||
//Open the device
|
||||
if ((err = snd_pcm_open(&this->waveHandle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
|
||||
printf("Playback open error: %s\n", snd_strerror(err));
|
||||
return;
|
||||
}
|
||||
//Set simple parameters
|
||||
if (( err = snd_pcm_set_params(
|
||||
this->waveHandle,
|
||||
this->waveFormat,
|
||||
this->waveAccess,
|
||||
this->currentChannels,
|
||||
this->currentSampleRate,
|
||||
1, //Allow alsa-lib software resampling
|
||||
500000) //Required overall latency (us) /* 0.5s */
|
||||
) > 0) { //If an error...
|
||||
printf("Playback open error: %s\n", snd_strerror(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Set the volume if it's not already set
|
||||
this->SetVolume(this->currentVolume);
|
||||
}
|
||||
}
|
103
src/contrib/alsaout/AlsaOut.h
Executable file
103
src/contrib/alsaout/AlsaOut.h
Executable file
@ -0,0 +1,103 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright © 2009, Julian Cromarty
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
#include "AlsaOutBuffer.h"
|
||||
/*
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#include <core/audio/IAudioCallback.h>
|
||||
#include <core/audio/IAudioOutput.h>
|
||||
*/
|
||||
#include <core/audio/IOutput.h>
|
||||
#include <list>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
class AlsaOut : public IOutput{
|
||||
public:
|
||||
AlsaOut();
|
||||
~AlsaOut();
|
||||
|
||||
virtual void Destroy();
|
||||
//virtual void Initialize(IPlayer *player);
|
||||
virtual void Pause();
|
||||
virtual void Resume();
|
||||
virtual void SetVolume(double volume);
|
||||
virtual void ClearBuffers();
|
||||
virtual bool PlayBuffer(IBuffer *buffer,IPlayer *player);
|
||||
virtual void ReleaseBuffers();
|
||||
|
||||
snd_pcm_t* getWaveHandle();
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<AlsaOutBuffer> AlsaOutBufferPtr;
|
||||
|
||||
//static void CALLBACK WaveCallback(HWAVEOUT hWave, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD dw2);
|
||||
void RemoveBuffer(AlsaOutBuffer *buffer);
|
||||
|
||||
private:
|
||||
void SetFormat(IBuffer *buffer);
|
||||
char *device; /* playback device */
|
||||
|
||||
protected:
|
||||
friend class AlsaOutBuffer;
|
||||
|
||||
//IPlayer *player;
|
||||
|
||||
// Audio stuff
|
||||
snd_output_t *output;
|
||||
snd_pcm_t *waveHandle;
|
||||
snd_pcm_format_t waveFormat;
|
||||
snd_pcm_access_t waveAccess;
|
||||
snd_pcm_hw_params_t *hw_params;
|
||||
|
||||
// Current format
|
||||
int currentChannels;
|
||||
long currentSampleRate;
|
||||
double currentVolume;
|
||||
|
||||
typedef std::list<AlsaOutBufferPtr> BufferList;
|
||||
BufferList buffers;
|
||||
BufferList removedBuffers;
|
||||
size_t maxBuffers;
|
||||
|
||||
boost::mutex mutex;
|
||||
|
||||
bool addToRemovedBuffers;
|
||||
|
||||
};
|
114
src/contrib/alsaout/AlsaOutBuffer.cpp
Executable file
114
src/contrib/alsaout/AlsaOutBuffer.cpp
Executable file
@ -0,0 +1,114 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright ﺏ 2007, Daniel ﺿnnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include "AlsaOutBuffer.h"
|
||||
#include "AlsaOut.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AlsaOutBuffer::AlsaOutBuffer(AlsaOut *alsaOut,IBuffer *buffer,IPlayer *player)
|
||||
:waveOut(alsaOut)
|
||||
,buffer(buffer)
|
||||
,player(player)
|
||||
{
|
||||
this->PrepareBuffer();
|
||||
}
|
||||
|
||||
void AlsaOutBuffer::PrepareBuffer(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "AlsaOutBuffer::PrepareBuffer()" << std::endl;
|
||||
#endif
|
||||
//unsigned float bufSize = this->buffer->Samples()*this->buffer->Channels()*sizeof(float);
|
||||
/*// Prepare the header
|
||||
this->header.dwBufferLength = this->buffer->Samples()*this->buffer->Channels()*sizeof(float);
|
||||
this->header.lpData = (LPSTR)this->buffer->BufferPointer();
|
||||
this->header.dwUser = (DWORD_PTR)this;
|
||||
this->header.dwBytesRecorded = 0;
|
||||
this->header.dwFlags = 0;
|
||||
this->header.dwLoops = 0;
|
||||
this->header.lpNext = NULL;
|
||||
this->header.reserved = NULL;
|
||||
|
||||
MMRESULT result = waveOutPrepareHeader(this->waveOut->waveHandle,&this->header,sizeof(WAVEHDR));
|
||||
if(result!=MMSYSERR_NOERROR){
|
||||
throw;
|
||||
}
|
||||
this->header.dwFlags |= WHDR_DONE;
|
||||
*/
|
||||
data = this->buffer->BufferPointer();
|
||||
bufferLength = this->buffer->Samples()*this->buffer->Channels()*sizeof(float);
|
||||
//TODO: Check data types.
|
||||
|
||||
}
|
||||
|
||||
AlsaOutBuffer::~AlsaOutBuffer(void)
|
||||
{
|
||||
this->player->ReleaseBuffer(this->buffer);
|
||||
}
|
||||
|
||||
bool AlsaOutBuffer::AddToOutput(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "AlsaOutBuffer::AddToOutput()" << std::endl;
|
||||
std::cerr << "Waveout: " << waveOut << std::endl;
|
||||
#endif
|
||||
/*MMRESULT result = waveOutWrite(this->waveOut->waveHandle,&this->header,sizeof(WAVEHDR));
|
||||
if(result==MMSYSERR_NOERROR){
|
||||
return true;
|
||||
}*/
|
||||
int err;
|
||||
snd_pcm_t* wHandle = waveOut->getWaveHandle();
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "whandle: " << wHandle << std::endl;
|
||||
std::cerr << "data: " << *data << std::endl;
|
||||
std::cerr << "bufferLength: " << bufferLength << std::endl;
|
||||
#endif
|
||||
if (wHandle == NULL) {
|
||||
printf("Error. No device handle \n");
|
||||
return false;
|
||||
}
|
||||
frames = snd_pcm_writei(wHandle, (void*)data, bufferLength);
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "frames: " << frames << std::endl;
|
||||
#endif
|
||||
if (frames < 0)
|
||||
frames = snd_pcm_recover(wHandle, frames, 0);
|
||||
if (frames < 0) {
|
||||
printf("snd_pcm_writei failed: %s\n", snd_strerror(err));
|
||||
return false;
|
||||
}
|
||||
if (frames > 0 && frames < (long)bufferLength) {
|
||||
printf("Short write (expected %li, wrote %li)\n", (long)bufferLength, frames);
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
|
69
src/contrib/alsaout/AlsaOutBuffer.h
Executable file
69
src/contrib/alsaout/AlsaOutBuffer.h
Executable file
@ -0,0 +1,69 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright <20> 2007, Daniel <20>nnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <core/audio/IBuffer.h>
|
||||
#include <core/audio/IPlayer.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declare
|
||||
class AlsaOut;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
class AlsaOutBuffer
|
||||
{
|
||||
public:
|
||||
AlsaOutBuffer(AlsaOut *waveOut,IBuffer *buffer,IPlayer *player);
|
||||
~AlsaOutBuffer(void);
|
||||
|
||||
bool AddToOutput();
|
||||
void PrepareBuffer();
|
||||
|
||||
AlsaOut *waveOut;
|
||||
IBuffer *buffer;
|
||||
IPlayer *player;
|
||||
|
||||
//snd_pcm_channel_area_t *areas;
|
||||
|
||||
private:
|
||||
snd_pcm_sframes_t frames;
|
||||
float* data;
|
||||
int bufferLength;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
28
src/contrib/alsaout/CMakeLists.txt
Executable file
28
src/contrib/alsaout/CMakeLists.txt
Executable file
@ -0,0 +1,28 @@
|
||||
set ( alsaout_SOURCES
|
||||
alsaout_plugin.cpp
|
||||
AlsaOut.cpp
|
||||
AlsaOutBuffer.cpp
|
||||
)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
add_definitions(-DWIN32)
|
||||
if(NOT DEFINED MINGW)
|
||||
|
||||
endif(NOT DEFINED MINGW)
|
||||
else(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -fpermissive)
|
||||
endif(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
|
||||
add_definitions(
|
||||
-DXML_STATIC
|
||||
-D_CRT_SECURE_NO_DEPRECATE
|
||||
-D_DEBUG
|
||||
)
|
||||
|
||||
#include_directories( ../../core )
|
||||
include_directories(/usr/include)
|
||||
|
||||
add_library( alsaout SHARED ${alsaout_SOURCES} )
|
||||
target_link_libraries( alsaout ${musikCube_LINK_LIBS} asound)
|
||||
|
||||
|
71
src/contrib/alsaout/alsaout_plugin.cpp
Executable file
71
src/contrib/alsaout/alsaout_plugin.cpp
Executable file
@ -0,0 +1,71 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2009, Julian Cromarty
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <core/IPlugin.h>
|
||||
#include "AlsaOut.h"
|
||||
|
||||
class AlsaOutPlugin : public musik::core::IPlugin
|
||||
{
|
||||
void Destroy() { delete this; };
|
||||
|
||||
const utfchar* Name() { return TEXT("AlsaOut output plugin"); };
|
||||
const utfchar* Version() { return TEXT("0.1"); };
|
||||
const utfchar* Author() { return TEXT("Julian Cromarty"); };
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
musik::core::IPlugin* GetPlugin()
|
||||
{
|
||||
return new AlsaOutPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
extern "C" {
|
||||
musik::core::audio::IAudioOutputSupplier* CreateAudioOutputSupplier()
|
||||
{
|
||||
return new AlsaOutSupplier();
|
||||
}
|
||||
}*/
|
||||
|
||||
extern "C" {
|
||||
musik::core::audio::IOutput* GetAudioOutput()
|
||||
{
|
||||
return new AlsaOut();
|
||||
}
|
||||
}
|
43
src/contrib/alsaout/pch.h
Executable file
43
src/contrib/alsaout/pch.h
Executable file
@ -0,0 +1,43 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright <20> 2008, Bj<42>rn Olievier
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Precompiled headers
|
||||
#pragma once
|
||||
|
||||
#include <core/config.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
Loading…
x
Reference in New Issue
Block a user