Beispiel #1
0
static int init(int rate_hz, int channels, int format, int flags)
{
	int err;
	int frag_spec;

	if( (err=arts_init()) ) {
		mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ARTS_CantInit, arts_error_text(err));
		return 0;
	}
	mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_ARTS_ServerConnect);

	/*
	 * arts supports 8bit unsigned and 16bit signed sample formats
	 * (16bit apparently in little endian format, even in the case
	 * when artsd runs on a big endian cpu).
	 *
	 * Unsupported formats are translated to one of these two formats
	 * using mplayer's audio filters.
	 */
	switch (format) {
	case AF_FORMAT_U8:
	case AF_FORMAT_S8:
	    format = AF_FORMAT_U8;
	    break;
	default:
	    format = AF_FORMAT_S16_LE;    /* artsd always expects little endian?*/
	    break;
	}

	ao_data.format = format;
	ao_data.channels = channels;
	ao_data.samplerate = rate_hz;
	ao_data.bps = (rate_hz*channels);

	if(format != AF_FORMAT_U8 && format != AF_FORMAT_S8)
		ao_data.bps*=2;

	stream=arts_play_stream(rate_hz, OBTAIN_BITRATE(format), channels, "MPlayer");

	if(stream == NULL) {
		mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ARTS_CantOpenStream);
		arts_free();
		return 0;
	}

	/* Set the stream to blocking: it will not block anyway, but it seems */
	/* to be working better */
	arts_stream_set(stream, ARTS_P_BLOCKING, 1);
	frag_spec = ARTS_PACKET_SIZE_LOG2 | ARTS_PACKETS << 16;
	arts_stream_set(stream, ARTS_P_PACKET_SETTINGS, frag_spec);
	ao_data.buffersize = arts_stream_get(stream, ARTS_P_BUFFER_SIZE);
	mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_ARTS_StreamOpen);

	mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_ARTS_BufferSize,
	    ao_data.buffersize);
	mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_ARTS_BufferSize,
	    arts_stream_get(stream, ARTS_P_PACKET_SIZE));

	return 1;
}
/* public methods (static but exported through the sysdep_dsp or plugin
   struct) */
static void *arts_dsp_create(const void *flags)
{
   struct sysdep_dsp_struct *dsp = NULL;
   struct arts_dsp_priv_data *priv = NULL;
   const struct sysdep_dsp_create_params *params = flags;
   
   
   /* allocate the dsp struct */
   if (!(dsp = calloc(1, sizeof(struct sysdep_dsp_struct))))
   {
      fprintf(stderr,
         "error malloc failed for struct sysdep_dsp_struct\n");
      return NULL;
   }

   if(!(priv = calloc(1, sizeof(struct arts_dsp_priv_data))))
   {
      fprintf(stderr,
         "error malloc failed for struct arts_dsp_priv_data\n");
      return NULL;
   }

   
   /* fill in the functions and some data */
   priv->stream=0; 
   dsp->_priv = priv;
   dsp->write = arts_dsp_write;
   dsp->destroy = arts_dsp_destroy;
   dsp->hw_info.type = params->type;
   dsp->hw_info.samplerate = params->samplerate;
   dsp->hw_info.bufsize = 1024;
   
   /* open the sound device */
   arts_init();
   priv->stream=arts_play_stream(dsp->hw_info.samplerate,
				 (dsp->hw_info.type&SYSDEP_DSP_16BIT)?16:8,
				 (dsp->hw_info.type&SYSDEP_DSP_STEREO)?2:1,
				 "xmame arts");
   
   /* Set the buffering time */
   arts_stream_set(priv->stream,ARTS_P_BUFFER_TIME,btime);

   /* set non-blocking mode if selected */
   if(params->flags & SYSDEP_DSP_O_NONBLOCK)
   {
	   arts_stream_set(priv->stream,ARTS_P_BLOCKING,0);
   }
   
   return dsp;
}
Beispiel #3
0
/* initialize the sound card or connect to aRts server */
void audio_init(audio_dev_handle* handle, int rate, int latency, int try_arts)
{
#ifdef HAS_ARTS
    int artserr = 0;

    handle->arts_handle = NULL;
    handle->use_arts    = 0;
#endif
    handle->alsa_handle = NULL;
    handle->channels    = 1;  /* mono */
    handle->format      = SND_PCM_FORMAT_U8;
    handle->rate        = rate;
    handle->latency     = latency; /* in ms */

#ifdef HAS_ARTS    
    if( try_arts )
    {
        artserr = arts_init();
        if( artserr < 0 )
        {
            fprintf(stderr, "Error initializing aRts: %s\n", arts_error_text(artserr));
            exit(-1);
        }
        handle->arts_handle = arts_play_stream( *rate, 8, handle->channels, "arts-whitenoise" );
        arts_stream_set(handle->arts_handle, ARTS_P_BUFFER_TIME, *latency);
        handle->use_arts = 1;
    }
    else
#endif
    {
        alsa_init(handle);
    }
}
Beispiel #4
0
static int acntl(int request, void *arg)
{
    int tmp, tmp1, samples;
    switch(request)
    {
      case PM_REQ_DISCARD: /* Discard stream */
	arts_close_stream(stream);
	stream=NULL;
	return 0;
      case PM_REQ_RATE: /* Change sample rate */
        arts_close_stream(stream);
        tmp = (dpm.encoding & PE_16BIT) ? 16 : 8;
        tmp1 = (dpm.encoding & PE_MONO) ? 1 : 2;
        stream = arts_play_stream(*(int*)arg,
		    LE_LONG(tmp),
		    tmp1,
		    "timidity");
        server_buffer = arts_stream_get(stream, ARTS_P_SERVER_LATENCY) * dpm.rate * (tmp/8) * tmp1 / 1000;
	return 0;
      case PM_REQ_GETQSIZ: /* Get maximum queue size */
	*(int*)arg = arts_stream_get(stream, ARTS_P_BUFFER_SIZE);
	return 0;
      case PM_REQ_SETQSIZ: /* Set queue size */
	*(int*)arg = arts_stream_set(stream, ARTS_P_BUFFER_SIZE, *(int*)arg);
	return 0;
      case PM_REQ_GETFRAGSIZ: /* Get device fragment size */
	*(int*)arg = arts_stream_get(stream, ARTS_P_PACKET_SIZE);
	return 0;
      case PM_REQ_GETSAMPLES: /* Get current play sample */
	tmp = arts_stream_get(stream, ARTS_P_BUFFER_SIZE) -
		         arts_stream_get(stream, ARTS_P_BUFFER_SPACE) +
			 server_buffer;
	samples = output_count - tmp;
	if(samples < 0)
	  samples = 0;
	if(!(dpm.encoding & PE_MONO)) samples >>= 1;
	if(dpm.encoding & PE_16BIT) samples >>= 1;
	*(int*)arg = samples;
	return 0;
      case PM_REQ_GETFILLABLE: /* Get fillable device queue size */
	*(int*)arg = arts_stream_get(stream, ARTS_P_BUFFER_SPACE);
	return 0;
      case PM_REQ_GETFILLED: /* Get filled device queue size */
	*(int*)arg = arts_stream_get(stream, ARTS_P_BUFFER_SIZE) - arts_stream_get(stream, ARTS_P_BUFFER_SPACE);
	return 0;
      /* The following are not (yet) implemented: */
      case PM_REQ_FLUSH: /* Wait until playback is complete */
      case PM_REQ_MIDI: /* Send MIDI event */
      case PM_REQ_INST_NAME: /* Get instrument name */
	return -1;
      case PM_REQ_OUTPUT_FINISH: /* Sent after last output_data */
      case PM_REQ_PLAY_START: /* Called just before playing */
      case PM_REQ_PLAY_END: /* Called just after playing */
	return 0;
    }
    return -1;
}
Beispiel #5
0
/* configure the audio buffer sizes.  The latency parameter is in millisec. */
void audio_set_latency(audio_dev_handle* handle, int latency)
{
    handle->latency = latency;
#ifdef HAS_ARTS
    if(handle->use_arts)
    {
        arts_close_stream(handle->arts_handle);
        handle->arts_handle = arts_play_stream(handle->rate, 8, handle->channels+1, "arts-whitenoise");
        arts_stream_set(handle->arts_handle, ARTS_P_BUFFER_TIME, latency);
    }
    else
#endif
    {
        snd_pcm_close(handle->alsa_handle);
        alsa_init(handle);
    }
}
Beispiel #6
0
static int op_arts_open(sample_format_t sf, const channel_position_t *channel_map)
{
	int buffer_time, server_latency, total_latency;
	int blocking;

	arts_sf = sf;
	arts_stream = arts_play_stream(sf_get_rate(arts_sf), sf_get_bits(arts_sf),
			sf_get_channels(arts_sf), "cmus");
	blocking = arts_stream_set(arts_stream, ARTS_P_BLOCKING, 0);
	if (blocking) {
	}
	arts_buffer_size = arts_stream_get(arts_stream, ARTS_P_BUFFER_SIZE);
	if (arts_buffer_size < 0) {
	}
	buffer_time = arts_stream_get(arts_stream, ARTS_P_BUFFER_TIME);
	server_latency = arts_stream_get(arts_stream, ARTS_P_SERVER_LATENCY);
	total_latency = arts_stream_get(arts_stream, ARTS_P_TOTAL_LATENCY);
	d_print("buffer_time: %d\n", buffer_time);
	d_print("server_latency: %d\n", server_latency);
	d_print("total_latency: %d\n", total_latency);
	return 0;
}
Beispiel #7
0
static int ARTSC_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	int bits, frag_spec;
	Uint16 test_format, format;

	/* Reset the timer synchronization flag */
	frame_ticks = 0.0;

	mixbuf = NULL;

	/* Try for a closest match on audio format */
	format = 0;
	bits = 0;
	for ( test_format = SDL_FirstAudioFormat(spec->format);
						! format && test_format; ) {
#ifdef DEBUG_AUDIO
		fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
#endif
		switch ( test_format ) {
			case AUDIO_U8:
				bits = 8;
				format = 1;
				break;
			case AUDIO_S16LSB:
				bits = 16;
				format = 1;
				break;
			default:
				format = 0;
				break;
		}
		if ( ! format ) {
			test_format = SDL_NextAudioFormat();
		}
	}
	if ( format == 0 ) {
		SDL_SetError("Couldn't find any hardware audio formats");
		return(-1);
	}
	spec->format = test_format;

	stream = arts_play_stream(spec->freq, bits, spec->channels, "SDL");

	/* Calculate the final parameters for this audio specification */
	SDL_CalculateAudioSpec(spec);

	/* Determine the power of two of the fragment size */
	for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec );
	if ( (0x01<<frag_spec) != spec->size ) {
		SDL_SetError("Fragment size must be a power of two");
		return(-1);
	}
	frag_spec |= 0x00020000;	/* two fragments, for low latency */

#ifdef ARTS_P_PACKET_SETTINGS
	arts_stream_set(stream, ARTS_P_PACKET_SETTINGS, frag_spec);
#else
	arts_stream_set(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff);
	arts_stream_set(stream, ARTS_P_PACKET_COUNT, frag_spec>>16);
#endif
	spec->size = arts_stream_get(stream, ARTS_P_PACKET_SIZE);

	/* Allocate mixing buffer */
	mixlen = spec->size;
	mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);
	if ( mixbuf == NULL ) {
		return(-1);
	}
	memset(mixbuf, spec->silence, spec->size);

	/* Get the parent process id (we're the parent of the audio thread) */
	parent = getpid();

	/* We're ready to rock and roll. :-) */
	return(0);
}
Beispiel #8
0
static int open_output(void)
{
    int i, include_enc, exclude_enc;
    int sample_width, channels;

    include_enc = 0;
    exclude_enc = PE_ULAW|PE_ALAW|PE_BYTESWAP; /* They can't mean these */
    if(dpm.encoding & PE_16BIT)
	include_enc |= PE_SIGNED;
    else
	exclude_enc |= PE_SIGNED;
    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);
    sample_width = (dpm.encoding & PE_16BIT) ? 16 : 8;
    channels = (dpm.encoding & PE_MONO) ? 1 : 2;

    /* Open the audio device */
    switch (arts_init_state) {
    case 0:
	if((i = arts_init()) != 0)
	{
	    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
		      dpm.name, arts_error_text(i));
	    return -1;
	}
	arts_init_state = 1;
	break;
    case 2:
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
	    "TiMidity aRts bug: open_output() after close_output() not supported");
	return -1;
    }
    stream = arts_play_stream(dpm.rate,
			      LE_LONG(sample_width),
			      channels,
			      "timidity");
    if(stream == NULL)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
		  dpm.name, strerror(errno));
	return -1;
    }
    arts_stream_set(stream, ARTS_P_BLOCKING, 1);

    server_buffer = arts_stream_get(stream, ARTS_P_SERVER_LATENCY) * dpm.rate * (sample_width/8) * channels / 1000;
    output_count = 0;
    return 0;
    /* "this aRts function isnot yet implemented"
     *
    if (dpm.extra_param[0]) {
        i = arts_stream_set(stream,
            ARTS_P_PACKET_COUNT,
            dpm.extra_param[0]);
	if (i < 0) {
            ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
              dpm.name, arts_error_text(i));
	    return 1;
        }
    }
    return 0;
     *
     */
}
Beispiel #9
0
/* public methods (static but exported through the sysdep_dsp or plugin
   struct) */
static void *arts_dsp_create(const void *flags)
{
   int i, j, result, bits, channels, block;
   struct arts_dsp_priv_data *priv = NULL;
   struct sysdep_dsp_struct *dsp = NULL;
   const struct sysdep_dsp_create_params *params = flags;
   
   /* allocate the dsp struct */
   if (!(dsp = calloc(1, sizeof(struct sysdep_dsp_struct))))
   {
      fprintf(stderr,
         "error malloc failed for struct sysdep_dsp_struct\n");
      return NULL;
   }
   
   /* alloc private data */
   if(!(priv = calloc(1, sizeof(struct arts_dsp_priv_data))))
   {
      fprintf(stderr,
         "error malloc failed for struct arts_dsp_priv_data\n");
      arts_dsp_destroy(dsp);
      return NULL;
   }
   
   /* fill in the functions and some data */
   priv->stream = NULL;
   dsp->_priv = priv;
   dsp->write = arts_dsp_write;
   dsp->destroy = arts_dsp_destroy;
   dsp->hw_info.type = params->type;
   dsp->hw_info.samplerate = params->samplerate;

   result = arts_init();
   if (result < 0)
   {
      fprintf(stderr,
         "arts_init error: %s\n", arts_error_text(result));
      arts_dsp_destroy(dsp);
      return NULL;
   }

   bits = (dsp->hw_info.type & SYSDEP_DSP_16BIT) ? 16 : 8;
   channels = (dsp->hw_info.type & SYSDEP_DSP_STEREO) ? 2 : 1;
   priv->stream = arts_play_stream(dsp->hw_info.samplerate, bits, channels,
      "xmame arts");

   block = (params->flags & SYSDEP_DSP_O_NONBLOCK) ? 0 : 1;
   result = arts_stream_set(priv->stream, ARTS_P_BLOCKING, block);
   if (result < 0)
   {
      fprintf(stderr,
         "arts_stream_set error: %s\n", arts_error_text(result));
      arts_dsp_destroy(dsp);
      return NULL;
   }
   else 
   {
      if (result != block)
      {
         fprintf(stderr,
            "arts_stream_set ARTS_P_BLOCKING to %d failed\n", block);
         arts_dsp_destroy(dsp);
         return NULL;
      }
   }

   /* calculate fragsize & number of frags */
   /* fragsize (as power of 2) */
   i = 7;
   if (dsp->hw_info.type & SYSDEP_DSP_16BIT) i++;
   if (dsp->hw_info.type & SYSDEP_DSP_STEREO) i++;
   i += dsp->hw_info.samplerate / 22050;
 
   /* number of frags */
   j = ((dsp->hw_info.samplerate * arts_dsp_bytes_per_sample[dsp->hw_info.type] * params->bufsize) / (0x01 << i)) + 1;

   arts_stream_set(priv->stream, ARTS_P_BUFFER_SIZE, (0x01<<i)*j);

#ifdef ARTS_DEBUG
   /* print some info messages ;) */
   fprintf(stderr, "info: aRts buffer size    : %d\n", 
      arts_stream_get(priv->stream, ARTS_P_BUFFER_SIZE));
   fprintf(stderr, "info: aRts buffer time    : %d\n",
      arts_stream_get(priv->stream, ARTS_P_BUFFER_TIME));
   fprintf(stderr, "info: aRts server latency : %d\n",
      arts_stream_get(priv->stream, ARTS_P_SERVER_LATENCY));
   fprintf(stderr, "info: aRts total latency  : %d\n",
      arts_stream_get(priv->stream, ARTS_P_TOTAL_LATENCY));
   fprintf(stderr, "info: aRts blocking       : %s\n",
      arts_stream_get(priv->stream, ARTS_P_BLOCKING) ? "yes" : "no");
#endif /* ifdef ARTS_DEBUG */

   return dsp;
}