[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    first stab at IRIX audio support for arts
From:       Jesse Barnes <jbarnes () sgi ! com>
Date:       2001-10-09 0:31:03
[Download RAW message or body]

This file is supposed to provide audio support for IRIX platforms, and it
somewhat works in that it opens the audio device and sets some
parameters.  'write()' is never called however.  I was hoping someone
who's done one of these AudioIO classes before could tell me what the
problem is.  Btw, thanks a lot Stephan, for writing the AudioIO class.  It
looks like a nice interface.

Thanks,
Jesse

/*
  
  Copyright (C) 2001 Jesse Barnes (jbarnes@sgi.com)
  Hacked up from audioionas.cc by Jochen Hoenicke
  
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.
    
  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
  
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/**
 * only compile dmedia AudioIO class if libaudio was detected during
 * configure
 */
#ifdef HAVE_LIBAUDIOSGI

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/stat.h>

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>

#include "audioio.h"
#include "debug.h"

#include <dmedia/audio.h>

namespace Arts {

class AudioIOSGI : public AudioIO {
protected:
	ALconfig config;
	ALport port;
	int dev;
	int bufsize;
	int framesize;

public:
	AudioIOSGI();

	void setParam(AudioParam param, int& value);
	int getParam(AudioParam param);

	bool open();
	void close();
	int read(void *buffer, int size);
	int write(void *buffer, int size);
};

REGISTER_AUDIO_IO(AudioIOSGI,"sgi","SGI Audio Library");
};

using namespace std;
using namespace Arts;

AudioIOSGI::AudioIOSGI()
{
	/*
	 * default parameters
	 */
	param(samplingRate) = 44100;
	param(channels) = 2;
	param(format) = 16;
	paramStr(deviceName) = "AnalogOut";
	param(fragmentSize) = -1;
	param(fragmentCount) = -1;
	param(direction) = 2;
	bufsize = 100000;
}

bool AudioIOSGI::open()
{
	ALpv params[1];
	int width;
	int fmt;
	string& _error = paramStr(lastError);

	if((param(direction) & directionRead))
	{
		_error = "read not implemented";
		return false;
	}

	/* 
	 * Find the resource that corresponds to deviceName
	 */
	dev = alGetResourceByName(AL_SYSTEM, (char *)paramStr(deviceName).c_str(), 
				  AL_OUTPUT_DEVICE_TYPE);

	/*
	 * Make sure we get a valid config handle
	 */
	if ( (config = alNewConfig()) == 0) {
		_error = "open: alNewConfig : " + (string)alGetErrorString(oserror());
		return false;
	}

	
	/*
	 * Hopefully we're using a twos complement sample format
	 * or it's is gonna sound weird.  Other formats for
	 * dmedia include AL_SAMPFMT_FLOAT and AL_SAMPFMT_DOUBLE
	 */
	fmt = AL_SAMPFMT_TWOSCOMP;
	if(alSetSampFmt(config, fmt) < 0) {
		_error = "open: alSetSampFmt : " + (string)alGetErrorString(oserror());
		return false;
	}

	/*
	 * Determine and set sample size
	 */
	switch (param(format))
	{
	case 8: /* 8 bit unsigned format */
		width = AL_SAMPLE_8;
		break;
	case 16: /* 16 bit signed LE */
		width = AL_SAMPLE_16;
		break;
	case 17: /* 16 bit signed BE */
		width = AL_SAMPLE_16;
		break;
	}
	if(alSetWidth(config, width) < 0) {
		_error = "open: alSetWidth : " + (string)alGetErrorString(oserror());
		return false;
	}

	/*
	 * Are we stereo or mono?
	 * TODO: use alGetParams to make sure we have the right number of channels
	 */
	if(alSetChannels(config, param(channels)) < 0) {
		_error = "open: alSetChannels : " + (string)alGetErrorString(oserror());
		_error += " : ";
		_error += param(channels);
		return false;
	}

	/*
	 * How big is one 'frame'?  Needed for alWriteFrames() and free()
	 */
	framesize = width * param(channels);	

	/*
	 * Set the queue size to the user configured buffer size
	 */
	if(alSetQueueSize(config, bufsize) < 0) {
		_error = "open: alSetQueueSize : " + (string)alGetErrorString(oserror());
		return false;
	}

	/*
	 * Set the device in the config structure
	 */
	if (alSetDevice(config, dev) < 0) {
		_error = "open: alSetDevice : " + (string)alGetErrorString(oserror());
		return false;
	}

	/*
	 * Setup the default output rate
	 */
	params[0].param = AL_RATE;
	params[0].sizeIn = 1;
	params[0].value.ll = alDoubleToFixed((double)param(samplingRate));
	if(alSetParams(dev, params, 1) < 0) {
		_error = "open: alSetParams : " + (string)alGetErrorString(oserror());
		_error += " rate: ";
		_error += param(samplingRate);
		return false;
	}
	
	/*
	 * The moment of truth, opening the port for writing
	 */
	if((port = alOpenPort("KDE", "w", config)) == NULL) {
		_error = "open: alOpenPort : " + (string)alGetErrorString(oserror());
		return false;
	}

	string success = "Successfully opened " + paramStr(deviceName);
	artsdebug(success.c_str());
	return true;
}

void AudioIOSGI::close()
{
	if (port) {
		alDiscardFrames(port, alGetFilled(port));
		alClosePort(port);
		alFreeConfig(config);
		artsdebug("Closed port");
	}
	
	return;
}

void AudioIOSGI::setParam(AudioParam p, int& value)
{
	artsdebug("setParam %d, %d", p, value);
	param(p) = value;
}

int AudioIOSGI::getParam(AudioParam p)
{
	artsdebug("getParam %d", p);
	switch(p)
	{
	case direction:
	case fragmentCount:
	case fragmentSize:
	case canRead:
	case canWrite:
	case selectFD:
	case autoDetect:
		return -1;		
	default:
		return param(p);
	}
}

int AudioIOSGI::read(void *, int )
{
	return 0;
}

int AudioIOSGI::write(void *buffer, int size)
{
	artsdebug("Writing %d bytes", size);
	/*
	 * Always returns 0 (according to man page :)
	 */
	alWriteFrames(port, buffer, size / framesize);

	artsdebug("Wrote %d bytes\n", size);

	return size;
}

#endif

 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic