示例#1
0
int main(int argc, char** argv)
{
	// zak³ada siê, ¿e ramka zawiera próbkê, w której
	// jest d¼wiêk beat-u i cisza do nastêpnego beatu
	// 
	//
	// ramka
	//char *pFrame;
	// licznik
	int i;
//	goc_termInit();
	printf(GOC_STRING_WHITE);

	// Procedury inicjuj±ce
	GOC_DEBUG("Initializing libao");
	ao_initialize();

	GOC_DEBUG("Initializing libao Device");
	aodriverid = ao_default_driver_id();
	if ( aodriverid == -1 )
		return -1;
	openOutputDevice();

	params = allocParameters();

	if ( argc > 1 )
	{
		if ( interpretArgs(argc, argv, params) < 0 )
			endProgram(-1);
	}


	GOC_DEBUG("Allocating buffer");

	generateBeat(params, BEAT_BASE);
	generateBeat(params, BEAT_ACCENT);
	generateBeat(params, BEAT_INTER);
	generateBeat(params, BEAT_QUIET);

//	pFrame = malloc(nFrame);
//	memset(pFrame, 0, nFrame);
	GOC_BINFO("Tempo: %d Rate: %d Channels: %d Bits: %d",
			params->tempo, SAMPLE_RATE, SAMPLE_CHANNELS, SAMPLE_BITS);
//	GOC_BDEBUG("Allocated %d at 0x%X", nFrame, (unsigned int)pFrame);
	if ( params->flags & FLAG_PRINTCOUNT )
	{
		goc_clearscreen();
		goc_gotoxy(1,1);
	}

	printf("Playing ... \n");
	if ( params->pattern )
		printf("Use pattern: %s\n", params->pattern);
	fflush(stdout);
	{
		// to nie do koñca jest liczba ramek - to jest liczba
		// podstawowych beatów jakie maj± zostaæ zagrane - nie
		// s± liczone beat-y po¶rednie
		int nFrames;
		int imeasure = 0;
		int iinter;
		int patternPosition = 0;
		int patternLen = 0;

		char *prevString = goc_stringCopy(NULL, "");
		char playedPattern = '.';

		if ( params->pattern )
		{
			patternLen = strlen(params->pattern);
		}

		if ( params->tacts )
			// na podstawie liczby podanych taktów
			nFrames = params->tacts * params->measure;
		else
			// na podstawie podanego czasu
			nFrames = params->tempo * params->pdur / 60;

		NEXTPATTERN();

		// goc_saveXY();
		for (i=0; i<nFrames; i++)
		{
			if ( imeasure )
			{
				if ( params->flags & FLAG_PRINTCOUNT )
				{
					goc_gotoxy(1, 5);
					printf("%s%s%s%d%s", GOC_STRING_YELLOW, prevString, GOC_STRING_BWHITE, imeasure + 1, GOC_STRING_YELLOW);
					prevString = goc_stringAddInt(prevString, imeasure+1);
					prevString = goc_stringAdd(prevString, " .. ");
					fflush(stdout);
				}
				if ( playedPattern == '.' )
					ao_play(aodev, params->pBeat[BEAT_BASE].pFrame, params->pBeat[BEAT_BASE].nFrame);
				else
					ao_play(aodev, params->pBeat[BEAT_QUIET].pFrame, params->pBeat[BEAT_QUIET].nFrame);
				NEXTPATTERN();
			}
			else
			{
				if ( params->flags & FLAG_PRINTCOUNT )
				{
					goc_gotoxy(1, 5);
					printf("%s%s", GOC_STRING_YELLOW, prevString);
					goc_gotoxy(1, 5);
					printf("%s%d%s", GOC_STRING_BWHITE, imeasure + 1, GOC_STRING_YELLOW);
					prevString = goc_stringFree(prevString);
					prevString = goc_stringAddInt(prevString, imeasure+1);
					prevString = goc_stringAdd(prevString, " .. ");

					fflush(stdout);
				}
				if ( playedPattern == '.' )
					ao_play(aodev, params->pBeat[BEAT_ACCENT].pFrame, params->pBeat[BEAT_ACCENT].nFrame);
				else
					ao_play(aodev, params->pBeat[BEAT_QUIET].pFrame, params->pBeat[BEAT_QUIET].nFrame);
				NEXTPATTERN();
			}
			if ( (iinter = params->inter) )
			{
				while  ( iinter-- )
				{
					if ( params->flags & FLAG_PRINTCOUNT )
					{
						goc_gotoxy(1, 5);
						printf("%s%s%si%s", GOC_STRING_YELLOW, prevString, GOC_STRING_WHITE, GOC_STRING_YELLOW);
						prevString = goc_stringAdd(prevString, "i .. ");
						fflush(stdout);
					}
					if ( playedPattern == '.' )
						ao_play(aodev, params->pBeat[BEAT_INTER].pFrame, params->pBeat[BEAT_INTER].nFrame);
					else
						ao_play(aodev, params->pBeat[BEAT_QUIET].pFrame, params->pBeat[BEAT_QUIET].nFrame);
					NEXTPATTERN();
				}
			}
			imeasure++;
			imeasure %= params->measure;
		}
		if ( params->flags & FLAG_PRINTCOUNT )
		{
			goc_gotoxy(1, 5);
			printf("%s%s", GOC_STRING_YELLOW, prevString);
		}
		prevString = goc_stringFree(prevString);
	}
	printf("%s\nFinish\n", GOC_STRING_WHITE);

	if ( params->tacts )
	{
		GOC_BINFO("Played %d frames in %d tacts", i, params->tacts);
	}
	else
	{
		GOC_BINFO("Played %d frames in %d seconds", i, params->pdur);
	}

	endProgram(0);
	return 0;
}
static int
stream_loop(mpg123_handle *mh, int socket)
{
    ao_device *dev;
    ao_sample_format format;
    size_t bytes_decoded;
    int status;
    unsigned char out_buffer[OUT_BUF_SIZE];
    int channels;
    int encoding;
    long rate;

    /* listen to socket */
    if (mpg123_open_fd(mh, socket) == MPG123_ERR) {
        fprintf(stderr, "%s\n", mpg123_strerror(mh));
        return 1;
    }

    status = MPG123_OK;

    /* set some standard format */
    memset(&format, 0, sizeof(ao_sample_format));
    format.rate = 44100;
    format.channels = 2;
    format.byte_format = AO_FMT_LITTLE;
    format.bits = 16;
    dev = ao_open_live(ao_default_driver_id(), &format, NULL);
    if (!dev) {
        fprintf(stderr, "ao_open_live failed()");
        return 1;
    }

    do {
        if (g_paused) {
            fprintf(stderr, "paused\n");
            sleep(1);
            continue;
        }
        status = mpg123_read(mh, out_buffer, OUT_BUF_SIZE, &bytes_decoded);
        if (status != 0) {
            fprintf(stderr, "status [%d] - %s\n", status, mpg123_plain_strerror(status));
        }
        if (status == MPG123_ERR || status == MPG123_DONE) {
            break;
        } else { 
            if (status == MPG123_NEW_FORMAT) {
                status = mpg123_getformat(mh, &rate, &channels, &encoding);
                fprintf(stderr, "new format:\n\trate: %ld\n\tchannels:%d\n\tencoding: %d\n",
                        rate, channels, encoding);
                format.rate = rate;
                format.channels = channels;
                format.byte_format = AO_FMT_LITTLE;
                format.bits = mpg123_encsize(encoding) * 8;
                /* close and reopen again for new format */
                ao_close(dev);
                dev = ao_open_live(ao_default_driver_id(), &format, NULL);
                if (!dev) {
                    fprintf(stderr, "ao_open_live failed\n");
                    break;
                }
            }
            if (dev) {
                ao_play(dev, (char*)out_buffer, bytes_decoded);
            }
        }
    } while (g_go_on && !g_stop);

    if (dev) {
        fprintf(stderr, "stderr close ao device\n");
        ao_close(dev);
    }
    return status;
}
示例#3
0
UINT8 StartStream(UINT8 DeviceID)
{
    UINT32 RetVal;
#ifdef USE_LIBAO
    ao_sample_format ao_fmt;
#else
#ifdef WIN32
    UINT16 Cnt;
    HANDLE WaveOutThreadHandle;
    DWORD WaveOutThreadID;
    //char TestStr[0x80];
#elif defined(__NetBSD__)
    struct audio_info AudioInfo;
#else
    UINT32 ArgVal;
#endif
#endif	// ! USE_LIBAO

    if (WaveOutOpen)
        return 0xD0;	// Thread is already active

    // Init Audio
    WaveFmt.wFormatTag = WAVE_FORMAT_PCM;
    WaveFmt.nChannels = 2;
    WaveFmt.nSamplesPerSec = SampleRate;
    WaveFmt.wBitsPerSample = 16;
    WaveFmt.nBlockAlign = WaveFmt.wBitsPerSample * WaveFmt.nChannels / 8;
    WaveFmt.nAvgBytesPerSec = WaveFmt.nSamplesPerSec * WaveFmt.nBlockAlign;
    WaveFmt.cbSize = 0;
    if (DeviceID == 0xFF)
        return 0x00;

#if defined(WIN32) || defined(USE_LIBAO)
    BUFFERSIZE = SampleRate / 100 * SAMPLESIZE;
    if (BUFFERSIZE > BUFSIZE_MAX)
        BUFFERSIZE = BUFSIZE_MAX;
#else
    BUFFERSIZE = 1 << BUFSIZELD;
#endif
    SMPL_P_BUFFER = BUFFERSIZE / SAMPLESIZE;
    if (AUDIOBUFFERU > AUDIOBUFFERS)
        AUDIOBUFFERU = AUDIOBUFFERS;

    PauseThread = true;
    ThreadPauseConfrm = false;
    CloseThread = false;
    StreamPause = false;

#ifndef USE_LIBAO
#ifdef WIN32
    ThreadPauseEnable = true;
    WaveOutThreadHandle = CreateThread(NULL, 0x00, &WaveOutThread, NULL, 0x00,
                                       &WaveOutThreadID);
    if(WaveOutThreadHandle == NULL)
        return 0xC8;		// CreateThread failed
    CloseHandle(WaveOutThreadHandle);

    RetVal = waveOutOpen(&hWaveOut, ((UINT)DeviceID - 1), &WaveFmt, 0x00, 0x00, CALLBACK_NULL);
    if(RetVal != MMSYSERR_NOERROR)
#else
    ThreadPauseEnable = false;
#ifdef __NetBSD__
    hWaveOut = open("/dev/audio", O_WRONLY);
#else
    hWaveOut = open("/dev/dsp", O_WRONLY);
#endif
    if (hWaveOut < 0)
#endif
#else	// ifdef USE_LIBAO
    ao_initialize();

    ThreadPauseEnable = false;
    ao_fmt.bits = WaveFmt.wBitsPerSample;
    ao_fmt.rate = WaveFmt.nSamplesPerSec;
    ao_fmt.channels = WaveFmt.nChannels;
    ao_fmt.byte_format = AO_FMT_NATIVE;
    ao_fmt.matrix = NULL;

    dev_ao = ao_open_live(ao_default_driver_id(), &ao_fmt, NULL);
    if (dev_ao == NULL)
#endif
    {
        CloseThread = true;
        return 0xC0;		// waveOutOpen failed
    }
    WaveOutOpen = true;

    //sprintf(TestStr, "Buffer 0,0:\t%p\nBuffer 0,1:\t%p\nBuffer 1,0:\t%p\nBuffer 1,1:\t%p\n",
    //		&BufferOut[0][0], &BufferOut[0][1], &BufferOut[1][0], &BufferOut[1][1]);
    //AfxMessageBox(TestStr);
#ifndef USE_LIBAO
#ifdef WIN32
    for (Cnt = 0x00; Cnt < AUDIOBUFFERU; Cnt ++)
    {
        WaveHdrOut[Cnt].lpData = BufferOut[Cnt];	// &BufferOut[Cnt][0x00];
        WaveHdrOut[Cnt].dwBufferLength = BUFFERSIZE;
        WaveHdrOut[Cnt].dwBytesRecorded = 0x00;
        WaveHdrOut[Cnt].dwUser = 0x00;
        WaveHdrOut[Cnt].dwFlags = 0x00;
        WaveHdrOut[Cnt].dwLoops = 0x00;
        WaveHdrOut[Cnt].lpNext = NULL;
        WaveHdrOut[Cnt].reserved = 0x00;
        RetVal = waveOutPrepareHeader(hWaveOut, &WaveHdrOut[Cnt], sizeof(WAVEHDR));
        WaveHdrOut[Cnt].dwFlags |= WHDR_DONE;
    }
#elif defined(__NetBSD__)
    AUDIO_INITINFO(&AudioInfo);

    AudioInfo.mode = AUMODE_PLAY;
    AudioInfo.play.sample_rate = WaveFmt.nSamplesPerSec;
    AudioInfo.play.channels = WaveFmt.nChannels;
    AudioInfo.play.precision = WaveFmt.wBitsPerSample;
    AudioInfo.play.encoding = AUDIO_ENCODING_SLINEAR;

    RetVal = ioctl(hWaveOut, AUDIO_SETINFO, &AudioInfo);
    if (RetVal)
        printf("Error setting audio information!\n");
#else
    ArgVal = (AUDIOBUFFERU << 16) | BUFSIZELD;
    RetVal = ioctl(hWaveOut, SNDCTL_DSP_SETFRAGMENT, &ArgVal);
    if (RetVal)
        printf("Error setting Fragment Size!\n");
    ArgVal = AFMT_S16_NE;
    RetVal = ioctl(hWaveOut, SNDCTL_DSP_SETFMT, &ArgVal);
    if (RetVal)
        printf("Error setting Format!\n");
    ArgVal = WaveFmt.nChannels;
    RetVal = ioctl(hWaveOut, SNDCTL_DSP_CHANNELS, &ArgVal);
    if (RetVal)
        printf("Error setting Channels!\n");
    ArgVal = WaveFmt.nSamplesPerSec;
    RetVal = ioctl(hWaveOut, SNDCTL_DSP_SPEED, &ArgVal);
    if (RetVal)
        printf("Error setting Sample Rate!\n");
#endif
#endif	// USE_LIBAO

    if (SoundLog)
        SaveFile(0x00000000, NULL);

    PauseThread = false;

    return 0x00;
}
示例#4
0
static int init(int argc, char **argv) {
  const char *str;
  int value;
  ao_initialize();
  int driver = ao_default_driver_id();
  ao_option *ao_opts = NULL;

  config.audio_backend_buffer_desired_length = 44100; // one second.
  config.audio_backend_latency_offset = 0;
  
  // get settings from settings file first, allow them to be overridden by command line options

  if (config.cfg != NULL) {
    /* Get the desired buffer size setting. */
    if (config_lookup_int(config.cfg, "ao.audio_backend_buffer_desired_length", &value)) {
      if ((value < 0) || (value > 66150))
        die("Invalid a0 audio backend buffer desired length \"%d\". It should be between 0 and "
            "66150, default is 44100",
            value);
      else {
        config.audio_backend_buffer_desired_length = value;
      }
    }
    
    /* Get the latency offset. */
    if (config_lookup_int(config.cfg, "ao.audio_backend_latency_offset", &value)) {
      if ((value < -66150) || (value > 66150))
        die("Invalid ao audio backend buffer latency offset \"%d\". It should be between -66150 and +66150, default is 0",
            value);
      else
        config.audio_backend_latency_offset = value;
    }
  }


  optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
  argv--;     // so we shift the arguments to satisfy getopt()
  argc++;

  // some platforms apparently require optreset = 1; - which?
  int opt;
  char *mid;
  while ((opt = getopt(argc, argv, "d:i:n:o:")) > 0) {
    switch (opt) {
    case 'd':
      driver = ao_driver_id(optarg);
      if (driver < 0)
        die("could not find ao driver %s", optarg);
      break;
    case 'i':
      ao_append_option(&ao_opts, "id", optarg);
      break;
    case 'n':
      ao_append_option(&ao_opts, "dev", optarg);
      // Old libao versions (for example, 0.8.8) only support
      // "dsp" instead of "dev".
      ao_append_option(&ao_opts, "dsp", optarg);
      break;
    case 'o':
      mid = strchr(optarg, '=');
      if (!mid)
        die("Expected an = in audio option %s", optarg);
      *mid = 0;
      ao_append_option(&ao_opts, optarg, mid + 1);
      break;
    default:
      help();
      die("Invalid audio option -%c specified", opt);
    }
  }

  if (optind < argc)
    die("Invalid audio argument: %s", argv[optind]);

  ao_sample_format fmt;
  memset(&fmt, 0, sizeof(fmt));

  fmt.bits = 16;
  fmt.rate = 44100;
  fmt.channels = 2;
  fmt.byte_format = AO_FMT_NATIVE;

  dev = ao_open_live(driver, &fmt, ao_opts);

  return dev ? 0 : 1;
}
示例#5
0
void VoxPlayer::aoplay(const std::string& path)
{
    m_isplaying = true;

    ao_device* ad = NULL;
    mpg123_handle* mh = NULL;
    unsigned char* buf = NULL;
    size_t bufsz = 0;
    size_t done = 0;
    int driver = ao_default_driver_id();
    ao_sample_format asf;
    int channels = 0;
    int encoding = 0;
    long rate = 0;
    
    if(!(mh = mpg123_new(NULL, NULL)))
    {
        ERROR("mpg123_new() failed");
        goto error_success;
    }

    bufsz = mpg123_outblock(mh);
    buf = (unsigned char*)malloc(bufsz * sizeof(unsigned char));
    
    if(mpg123_open(mh, path.c_str()) != MPG123_OK)
    {
        ERROR("mpg123_open() failed");
        goto error_success;
    }

    mpg123_volume(mh, 1.4);

    if(mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK)
    {
        ERROR("mpg123_getformat() failed");
        goto error_success;
    }

    asf.bits = mpg123_encsize(encoding) * 8; // BITS
    asf.rate = rate;
    asf.channels = channels;
    asf.byte_format = AO_FMT_NATIVE;
    asf.matrix = 0;

    if(!(ad = ao_open_live(driver, &asf, NULL)))
    {
        ERROR("ao_open_live() failed");
        goto error_success;
    }
    
    while(!g_main.isExit() && !m_interrupt)
    {
        int ret = mpg123_read(mh, buf, bufsz, &done);

        DEBUG("ret=%d, done=%d", ret, done);

        if(ret == MPG123_OK || ret == MPG123_DONE || ret == MPG123_NEED_MORE)
        {
            if(!ao_play(ad, (char*)buf, done))
            {
                ERROR("ao_play() failed");
                break;
            }

            if(ret == MPG123_DONE)
                break;

            continue;
        }

        break;
    }

    DEBUG("play done");

error_success:

    if(buf)
    {
        free(buf);
        buf = NULL;
    }

    if(ad)
    {
        ao_close(ad);
        ad = NULL;
    }

    if(mh)
    {
        mpg123_close(mh);
        mpg123_delete(mh);
        mh = NULL;
    }

    m_isplaying = false;
}
示例#6
0
文件: player.c 项目: jenikm/pianobar
/*	mp3 playback callback
 */
static WaitressCbReturn_t BarPlayerMp3Cb (void *ptr, size_t size,
		void *stream) {
	const char *data = ptr;
	struct audioPlayer *player = stream;
	size_t i;

	if (BarPlayerCheckPauseQuit (player) ||
			!BarPlayerBufferFill (player, data, size)) {
		return WAITRESS_CB_RET_ERR;
	}

	/* some "prebuffering" */
	if (player->mode < PLAYER_RECV_DATA &&
			player->bufferFilled < BAR_PLAYER_BUFSIZE / 2) {
		return WAITRESS_CB_RET_OK;
	}

	mad_stream_buffer (&player->mp3Stream, player->buffer,
			player->bufferFilled);
	player->mp3Stream.error = 0;
	do {
		/* channels * max samples, found in mad.h */
		signed short int madDecoded[2*1152], *madPtr = madDecoded;

		if (mad_frame_decode (&player->mp3Frame, &player->mp3Stream) != 0) {
			if (player->mp3Stream.error != MAD_ERROR_BUFLEN) {
				BarUiMsg (player->settings, MSG_ERR,
						"mp3 decoding error: %s\n",
						mad_stream_errorstr (&player->mp3Stream));
				return WAITRESS_CB_RET_ERR;
			} else {
				/* rebuffering required => exit loop */
				break;
			}
		}
		mad_synth_frame (&player->mp3Synth, &player->mp3Frame);
		for (i = 0; i < player->mp3Synth.pcm.length; i++) {
			/* left channel */
			*(madPtr++) = applyReplayGain (BarPlayerMadToShort (
					player->mp3Synth.pcm.samples[0][i]), player->scale);

			/* right channel */
			*(madPtr++) = applyReplayGain (BarPlayerMadToShort (
					player->mp3Synth.pcm.samples[1][i]), player->scale);
		}
		if (player->mode < PLAYER_AUDIO_INITIALIZED) {
			ao_sample_format format;
			int audioOutDriver;

			player->channels = player->mp3Synth.pcm.channels;
			player->samplerate = player->mp3Synth.pcm.samplerate;
			audioOutDriver = ao_default_driver_id();
			memset (&format, 0, sizeof (format));
			format.bits = 16;
			format.channels = player->channels;
			format.rate = player->samplerate;
			format.byte_format = AO_FMT_NATIVE;
			if ((player->audioOutDevice = ao_open_live (audioOutDriver,
					&format, NULL)) == NULL) {
				player->aoError = 1;
				BarUiMsg (player->settings, MSG_ERR,
						"Cannot open audio device\n");
				return WAITRESS_CB_RET_ERR;
			}

			/* calc song length using the framerate of the first decoded frame */
			player->songDuration = (unsigned long long int) player->waith.request.contentLength /
					((unsigned long long int) player->mp3Frame.header.bitrate /
					(unsigned long long int) BAR_PLAYER_MS_TO_S_FACTOR / 8LL);

			/* must be > PLAYER_SAMPLESIZE_INITIALIZED, otherwise time won't
			 * be visible to user (ugly, but mp3 decoding != aac decoding) */
			player->mode = PLAYER_RECV_DATA;
		}
		/* samples * length * channels */
		ao_play (player->audioOutDevice, (char *) madDecoded,
				player->mp3Synth.pcm.length * 2 * 2);

		/* avoid division by 0 */
		if (player->mode == PLAYER_RECV_DATA) {
			/* same calculation as in aac player; don't need to divide by
			 * channels, length is number of samples for _one_ channel */
			player->songPlayed += (unsigned long long int) player->mp3Synth.pcm.length *
					(unsigned long long int) BAR_PLAYER_MS_TO_S_FACTOR /
					(unsigned long long int) player->samplerate;
		}

		if (BarPlayerCheckPauseQuit (player)) {
			return WAITRESS_CB_RET_ERR;
		}
	} while (player->mp3Stream.error != MAD_ERROR_BUFLEN);

	player->bufferRead += player->mp3Stream.next_frame - player->buffer;

	BarPlayerBufferMove (player);

	return WAITRESS_CB_RET_OK;
}
示例#7
0
文件: aosound.c 项目: CiaranG/ZXdroid
int
sound_lowlevel_init( const char *device, int *freqptr, int *stereoptr )
{
  ao_option *options = NULL;
  ao_info *driver_info = NULL;
  int driver_id = -1;
  static ao_sample_format format = { .bits = 0 };

  /* To prevent recursive errors */
  static int sound_lowlevel_init_in_progress = 0;

  int error;

  if( sound_lowlevel_init_in_progress ) return 0;

  sound_lowlevel_init_in_progress = 1;

  ao_initialize();

  error = parse_driver_options( device, &driver_id, &options );
  if( error ) {
    settings_current.sound = 0;
    sound_lowlevel_init_in_progress = 0;
    return error;
  }

  if( driver_id == -1 )
    driver_id = ao_default_driver_id();

  if( driver_id == -1 ) {
    ui_error( UI_ERROR_ERROR, "ao: driver '%s' unknown",
              device );
    settings_current.sound = 0;
    sound_lowlevel_init_in_progress = 0;
    return 1;
  }

  driver_info = ao_driver_info( driver_id );
  
  if( driver_info->type == AO_TYPE_FILE &&
      format.bits != 0 ) {	/* OK. We not want to trunc the file :-) */
    ui_error( UI_ERROR_WARNING, "ao: must truncate audio file '%s'",
	      filename );
  }

  format.channels = *stereoptr ? 2 : 1;
  format.rate = *freqptr;
  format.bits = settings_current.sound_force_8bit ? 8 : 16;
  format.byte_format = AO_FMT_LITTLE;
  sixteenbit = settings_current.sound_force_8bit ? 0 : 1;
  
  if( driver_info->type == AO_TYPE_LIVE ) {

    dev_for_ao = ao_open_live( driver_id, &format, options);

  } else {

    if( !filename ) filename = (char *)default_filename;
    dev_for_ao = ao_open_file( driver_id, filename, 1, &format, options);

  }

  if( !dev_for_ao ) {
    driver_error();
    settings_current.sound = 0;
    sound_lowlevel_init_in_progress = 0;
    return 1;
  }

  ao_free_options( options );
  
  sound_lowlevel_init_in_progress = 0;
  first_init = 0;

  return 0;
}

void
sound_lowlevel_end( void )
{
  if( filename != default_filename ) free( filename );
  ao_close(dev_for_ao);
  ao_shutdown();
}

void
sound_lowlevel_frame( libspectrum_signed_word *data, int len )
{
  static signed char buf8[4096];
  void *data8 = data;

  len <<= 1;	/* now in bytes */

  if( !sixteenbit ) {
    libspectrum_signed_word *src;
    signed char *dst;
    int f;

    src = data;
    dst = buf8;
    len >>= 1;
    for( f = 0; f < len; f++)
      *dst++ = ( int )( ( *src++ ) / 256 );
  
    data8 = buf8;
  }

  ao_play( dev_for_ao, data8, len );
}
示例#8
0
int playfile(FILE *fp)
{
    int default_driver;
    int frames_read;
    int count;
    int toread;
    int readnow;
    short *buffer;
    short *groovy;
    long filestart;

    ao_device *device;
    ao_sample_format format;

    SNDFILE     *sndfile;
    SF_INFO     sf_info;


    ao_initialize();
    default_driver = ao_default_driver_id();

    sf_info.format = 0;

    filestart = ftell(fp);

    sndfile = sf_open_fd(fileno(fp), SFM_READ, &sf_info, 0);

    memset(&format, 0, sizeof(ao_sample_format));

    format.byte_format = AO_FMT_NATIVE;
    format.bits = 16;
    format.rate = sf_info.samplerate;
//    format.channels = sf_info.channels;
    format.channels = 2;

    printf("Channels: %d\n", sf_info.channels);
    printf("Samplerate: %d\n", sf_info.samplerate);

    device = ao_open_live(default_driver, &format, NULL);
    if (device == NULL) {
        printf("Error opening sound device.\n");
        return 1;
    }

    buffer = malloc(BUFFSIZE * sf_info.channels * sizeof(short));
    groovy = malloc(BUFFSIZE * 2 * sizeof(short));

    frames_read = 0;
    toread = sf_info.frames * sf_info.channels;

    while (toread > 0) {
	if (toread < BUFFSIZE * sf_info.channels)
	    count = toread;
	else
	    count = BUFFSIZE * sf_info.channels;

        frames_read = sf_read_short(sndfile, buffer, count);

	if (sf_info.channels == 1)
	    stereoize(groovy, buffer, count * sizeof(short));
	else
	    memcpy(groovy, buffer, count * sizeof(short));

        ao_play(device, (char *)groovy, frames_read * sizeof(short));
	toread = toread - frames_read;
    }

    free(buffer);
    free(groovy);
    fseek(fp, filestart, SEEK_SET);
    ao_close(device);
    sf_close(sndfile);
    ao_shutdown();
    printf("Finished\n");

    return 0;
}
示例#9
0
文件: snd_ao.c 项目: luaman/qforge-2
/* SNDDMA_Init: initialises cycling through a DMA bufffer and returns
 *  information on it
 */
qboolean SNDDMA_Init(struct sndinfo * s){
	int driver_id;
	ao_sample_format format;
	ao_option * options = NULL;
	
	if(snd_inited)
		return 1;
		
	snd_inited = 0;
	
	si = s;
	
	ao_initialize();
	
	if((driver_id = ao_driver_id(si->device->string)) == -1){
		si->Com_Printf("ao: no driver %s found, trying default\n", si->device->string);
		if((driver_id = ao_default_driver_id()) == -1){
			Com_Printf("ao: no default driver found\n");
			return 0;
		}
	}
	
	format.bits = si->dma->samplebits = si->bits->value;
	format.rate = si->dma->speed = 44100;
	format.channels = si->dma->channels = si->channels->value;
	format.byte_format = AO_FMT_NATIVE;
	
	switch(si->dma->speed){
		case 44100:
			si->dma->samples = 2048 * si->dma->channels;
			break;
		case 22050:
			si->dma->samples = 1024 * si->dma->channels;
			break;
		default:
			si->dma->samples = 512 * si->dma->channels;
			break;
	}
	
	if((device = ao_open_live(driver_id, &format, options)) == NULL){
		switch(errno){
			case AO_ENODRIVER:
				Com_Printf("ao: no driver for %d\n", driver_id);
				break;
			case AO_ENOTLIVE:
				Com_Printf("ao: not a valid live output device\n");
				break;
			case AO_EBADOPTION:
				Com_Printf("ao: valid option has invalid key\n");
				break;
			case AO_EOPENDEVICE:
				Com_Printf("ao: cannot open device\n");
				break;
			case AO_EFAIL:
				Com_Printf("ao: something broke during ao_open_live\n");
				break;
			case AO_ENOTFILE:
				Com_Printf("ao: not a file\n");
				break;
			case AO_EOPENFILE:
				Com_Printf("ao: can't open file\n");
				break;
			case AO_EFILEEXISTS:
				Com_Printf("ao: file exists already\n");
				break;
			default:
				Com_Printf("ao: whoa, bad trip dude\n");
				break;
		}
		return 0;
	}
	
	samplesize = si->dma->samplebits >> 3;
	si->dma->buffer = malloc(si->dma->samples * samplesize);
	memset(si->dma->buffer, 0, si->dma->samples * samplesize);
	
	si->dma->samplepos = 0;
	si->dma->submission_chunk = 1;
	
	si->Com_Printf("ao: buffer size is %d, %d samples\n", si->dma->samples * samplesize, si->dma->samples);
	
	snd_inited = 1;
	return 1;
}
示例#10
0
static void *
ao_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
	       const struct config_param *param,
	       GError **error)
{
	struct ao_data *ad = g_new(struct ao_data, 1);
	ao_info *ai;
	const char *value;

	ad->options = NULL;

	ad->write_size = config_get_block_unsigned(param, "write_size", 1024);

	if (ao_output_ref == 0) {
		ao_initialize();
	}
	ao_output_ref++;

	value = config_get_block_string(param, "driver", "default");
	if (0 == strcmp(value, "default"))
		ad->driver = ao_default_driver_id();
	else
		ad->driver = ao_driver_id(value);

	if (ad->driver < 0) {
		g_set_error(error, ao_output_quark(), 0,
			    "\"%s\" is not a valid ao driver",
			    value);
		g_free(ad);
		return NULL;
	}

	if ((ai = ao_driver_info(ad->driver)) == NULL) {
		g_set_error(error, ao_output_quark(), 0,
			    "problems getting driver info");
		g_free(ad);
		return NULL;
	}

	g_debug("using ao driver \"%s\" for \"%s\"\n", ai->short_name,
		config_get_block_string(param, "name", NULL));

	value = config_get_block_string(param, "options", NULL);
	if (value != NULL) {
		gchar **options = g_strsplit(value, ";", 0);

		for (unsigned i = 0; options[i] != NULL; ++i) {
			gchar **key_value = g_strsplit(options[i], "=", 2);

			if (key_value[0] == NULL || key_value[1] == NULL) {
				g_set_error(error, ao_output_quark(), 0,
					    "problems parsing options \"%s\"",
					    options[i]);
				g_free(ad);
				return NULL;
			}

			ao_append_option(&ad->options, key_value[0],
					 key_value[1]);

			g_strfreev(key_value);
		}

		g_strfreev(options);
	}

	return ad;
}
示例#11
0
文件: audio.c 项目: olynch/fp_mario
void au_initEach(){
  default_driver = ao_default_driver_id();
  device = ao_open_live(default_driver, &format, NULL);
  /* signal(SIGTERM, au_deinitEach); */
}
示例#12
0
文件: ao.cpp 项目: udoprog/momd
void output_ao::setup(libconfig::Setting& setting)
{
    int channels;
    int rate;
    int bps;
    std::string driver;
    
    if (setting.lookupValue("channels", channels)) {
        setting.remove("channels");
        format.channels = channels;
    }
    else {
        format.channels = DEFAULT_GLOBAL_CHANNELS;
    }
    
    if (setting.lookupValue("rate", rate)) {
        setting.remove("rate");
        format.rate = rate;
    }
    else {
        format.rate = 44100;
    }
    
    if (setting.lookupValue("bps", bps)) {
        setting.remove("bps");
        format.bits = bps;
    }
    else {
        format.bits = 16;
    }
    
    format.byte_format = AO_FMT_LITTLE;
    
    if (setting.lookupValue("driver", driver)) {
        setting.remove("driver");
        driver = ao_driver_id(driver.c_str());
    }
    else {
        driver = ao_default_driver_id();
    }
    
    int length = setting.getLength();

    ao_option *current = NULL;
    
    for (int i = 0; i < length; i++) {
        libconfig::Setting& s = setting[i];

        if (current == NULL) {
            current = new ao_option;
            options = current;
        }
        else {
            current->next = new ao_option;
        }

        std::string key = s.getName();
        std::string value = s;

        current->key = new char[key.size() + 1];
        current->value = new char[value.size() + 1];

        ::strncpy(current->key, key.c_str(), key.size());
        ::strncpy(current->value, value.c_str(), value.size());
    }
}
示例#13
0
int main(int argc, char **argv)
{
	int r, tmp, fi, random=0;
	char Buffer[1024];
	char length_str[256], fade_str[256], volume[256], title_str[256];
	char tmp_str[256];
	char *tag;

	soundLowPass = 0;
	soundEcho = 0;
	soundQuality = 0;

	DetectSilence=1;
	silencelength=5;	
	IgnoreTrackLength=0;
	DefaultLength=150000;
	TrailingSilence=1000;
	playforever=0;
	

	while((r=getopt(argc, argv, "hlsrieWL:t:"))>=0)	
	{
		char *e;
		switch(r)
		{
			case 'h':
				printf("playgsf version %s (based on Highly Advanced version %s)\n\n", 
						VERSION_STR, HA_VERSION_STR);
				printf("Usage: ./playgsf [options] files...\n\n");
				printf("  -l        Enable low pass filer\n");
				printf("  -s        Detect silence\n");
				printf("  -L        Set silence length in seconds (for detection). Default 5\n");
				printf("  -t        Set default track length in milliseconds. Default 150000 ms\n");
				printf("  -i        Ignore track length (use default length)\n");
				printf("  -e        Endless play\n");
				printf("  -r        Play files in random order\n");
				printf("  -W        output to 'output.wav' rather than soundcard\n");
				printf("  -h        Displays what you are reading right now\n");
				return 0;
				break;
			case 'i':
				IgnoreTrackLength = 1;
				break;
			case 'l':
				soundLowPass = 1;
				break;
			case 's':
				DetectSilence = 1;
				break;
			case 'L':
				silencelength = strtol(optarg, &e, 0);
				if (e==optarg) {
					fprintf(stderr, "Bad value\n");
					return 1;
				}				
				break;
			case 'e':
				playforever = 1;
				break;
			case 't':
				DefaultLength = strtol(optarg, &e, 0);
				if (e==optarg) {
					fprintf(stderr, "Bad value\n");
					return 1;
				}				
				break;
			case 'r':
				random = 1;				
				break;
			case 'W':
				fileoutput = 1;
				break;
			case '?':
				fprintf(stderr, "Unknown argument. try -h\n");
				return 1;
				break;
		}
	}
	
	if (argc-optind<=0) {
		printf("No files specified! For help, try -h\n");
		return 1;
	}


	if (random) { shuffle_list(&argv[optind], argc-optind); }

	printf("playgsf version %s (based on Highly Advanced version %s)\n\n", 
				VERSION_STR, HA_VERSION_STR);

	signal(SIGINT, signal_handler);

	tag = (char*)malloc(50001);

	fi = optind;
	while (!g_must_exit && fi < argc)
	{
		decode_pos_ms = 0;
		seek_needed = -1;
		TrailingSilence=1000;
		
		r = GSFRun(argv[fi]);
		if (!r) {
			fi++;
			continue;
		}

		g_playing = 1;

		psftag_readfromfile((void*)tag, argv[fi]);
	
		BOLD(); printf("Filename: "); NORMAL();
		printf("%s\n", basename(argv[fi]));
		BOLD(); printf("Channels: "); NORMAL();
		printf("%d\n", sndNumChannels);
		BOLD(); printf("Sample rate: "); NORMAL();
		printf("%d\n", sndSamplesPerSec);
		
		if (!psftag_getvar(tag, "title", title_str, sizeof(title_str)-1)) {
			BOLD(); printf("Title: "); NORMAL();
			printf("%s\n", title_str);
		}
		
		if (!psftag_getvar(tag, "artist", tmp_str, sizeof(tmp_str)-1)) {
			BOLD(); printf("Artist: "); NORMAL();
			printf("%s\n", tmp_str);
		}
		
		if (!psftag_getvar(tag, "game", tmp_str, sizeof(tmp_str)-1)) {
			BOLD(); printf("Game: "); NORMAL();
			printf("%s\n", tmp_str);
		}
		
		if (!psftag_getvar(tag, "year", tmp_str, sizeof(tmp_str)-1)) {
			BOLD(); printf("Year: "); NORMAL();
			printf("%s\n", tmp_str);
		}
		
		if (!psftag_getvar(tag, "copyright", tmp_str, sizeof(tmp_str)-1)) {
			BOLD(); printf("Copyright: "); NORMAL();
			printf("%s\n", tmp_str);
		}
		
		if (!psftag_getvar(tag, "gsfby", tmp_str, sizeof(tmp_str)-1)) {
			BOLD(); printf("GSF By: "); NORMAL();
			printf("%s\n", tmp_str);
		}
		
		if (!psftag_getvar(tag, "tagger", tmp_str, sizeof(tmp_str)-1)) {
			BOLD(); printf("Tagger: "); NORMAL();
			printf("%s\n", tmp_str);
		}
		
		if (!psftag_getvar(tag, "comment", tmp_str, sizeof(tmp_str)-1)) {
			BOLD(); printf("Comment: "); NORMAL();
			printf("%s\n", tmp_str);
		}
		
		if (!psftag_getvar(tag, "fade", fade_str, sizeof(fade_str)-1)) {
			FadeLength = LengthFromString(fade_str);
			BOLD(); printf("Fade: "); NORMAL();
			printf("%s (%d ms)\n", fade_str, FadeLength);
		}
		
		if (!psftag_raw_getvar(tag, "length", length_str, sizeof(length_str)-1)) {
			TrackLength = LengthFromString(length_str) + FadeLength;
			BOLD(); printf("Length: "); NORMAL();
			printf("%s (%d ms) ", length_str, TrackLength);
			if (IgnoreTrackLength) {
				printf("(ignored)");
				TrackLength = DefaultLength;
			}
			printf("\n");
		}
		else {
			TrackLength = DefaultLength;
		}


		/* Must be done after GSFrun so sndNumchannels and 
		 * sndSamplesPerSec are set to valid values */
		ao_initialize();
		ao_sample_format format_ao = {
		  16, sndSamplesPerSec, sndNumChannels, AO_FMT_LITTLE
		};
		if(fileoutput) {
		  snd_ao = ao_open_file(ao_driver_id("wav"),
					"output.wav", 1,
					&format_ao,
					NULL);
		} else {
		  snd_ao = ao_open_live(ao_default_driver_id(),
					&format_ao,
					NULL);
		}
		
		while(g_playing)
		{
			int remaining = TrackLength - (int)decode_pos_ms;
			if (remaining<0) { 
				// this happens during silence period
				remaining = 0;
			}
			EmulationLoop();
		
			BOLD(); printf("Time: "); NORMAL();
			printf("%02d:%02d.%02d ",
					(int)(decode_pos_ms/1000.0)/60,
					(int)(decode_pos_ms/1000.0)%60,
					(int)(decode_pos_ms/10.0)%100);
			if (!playforever) {
				/*BOLD();*/ printf("["); /*NORMAL();*/
				printf("%02d:%02d.%02d",
					remaining/1000/60, (remaining/1000)%60, (remaining/10%100)
						);
				/*BOLD();*/ printf("] of "); /*NORMAL();*/
				printf("%02d:%02d.%02d ", 
					TrackLength/1000/60, (TrackLength/1000)%60, (TrackLength/10%100)); 
			}
			BOLD(); printf("  GBA Cpu: "); NORMAL();
			printf("%02d%% ", cpupercent);
			printf("     \r");
			
			fflush(stdout);
		}
		printf("\n--\n");
		ao_close(snd_ao);
		fi++;
	}

	ao_shutdown();
	return 0;
}
示例#14
0
int playback(FILE * streamfd, int pipefd) {
	killed = 0;
	signal(SIGUSR1, sighand);

#ifndef EXTERN_ONLY
	if(!haskey(& rc, "extern")) {
		const char * freetrack = NULL;

		struct stream data;
		struct mad_decoder dec;

#ifdef LIBAO
		static int ao_initialized = 0;

		if(!ao_initialized) {
			ao_initialize();
			ao_initialized = !0;
		}
#else
		unsigned arg;
		int fd;
#endif

		memset(& data, 0, sizeof(struct stream));

		/*
			Check if there's a stream timeout configured and set it up for timed
			reads later.
		*/
		data.timeout = -1;
		if(haskey(& rc, "stream-timeout")) {
			const char * timeout = value(& rc, "stream-timeout");
			data.timeout = atoi(timeout);

			if(data.timeout <= 0) {
				if(data.timeout < 0) 
					fputs("Invalid stream-timeout.\n", stderr);

				data.timeout = -1;
			}
		}


		data.streamfd = streamfd;
		data.parent = getppid();
		data.pipefd = pipefd;
		fcntl(pipefd, F_SETFL, O_NONBLOCK);

#ifdef LIBAO
		data.driver_id = ao_default_driver_id();

		if(-1 == data.driver_id) {
			fputs("Unable to find any usable output device!\n", stderr);
			return 0;
		}

		data.fmt.bits = 16;
		data.fmt.rate = 44100;
		data.fmt.channels = 2;
		data.fmt.byte_format = AO_FMT_NATIVE;
		data.device = ao_open_live(data.driver_id,&data.fmt,NULL);

		if(NULL == data.device) {
			fprintf(stderr, "Unable to open device. %s.\n", strerror(errno));
			return 0;
		}
#else
		data.audiofd = fd = open(value(& rc, "device"), O_WRONLY);

		if(-1 == data.audiofd) {
			fprintf(
					stderr, "Couldn't open %s! %s.\n",
					value(& rc, "device"), strerror(errno)
			);
			return 0;
		}

		arg = 16; /* 16 bits */
		ioctl(data.audiofd, SOUND_PCM_WRITE_BITS, & arg);
#endif

		freetrack = value(& track, "freeTrackURL");

		if(freetrack && strlen(freetrack) > 0 && haskey(& rc, "download")) {
			char * dnam;
			int rv;

			data.finpath = strdup(meta(value(& rc, "download"), M_RELAXPATH, & track));
			assert(data.finpath != NULL);

			data.tmppath = strjoin("", data.finpath, ".streaming", NULL);
			assert(data.tmppath != NULL);

			dnam = strdup(data.tmppath);
			rv = dnam ? mkpath(dirname(dnam)) : -1;
			free(dnam);

			if(access(data.tmppath, R_OK) == -1) {
				data.dump = (rv == 0) ? fopen(data.tmppath, "w") : NULL;

				if(!data.dump)
					fprintf(stderr, "Can't write download to %s.\n", data.tmppath);
			}
			else {
				data.dump = NULL;
			}
		}

		mad_decoder_init(& dec, & data, input, NULL, NULL, output, NULL, NULL);
		mad_decoder_run(& dec, MAD_DECODER_MODE_SYNC);
#ifndef LIBAO
		close(fd);
#endif
		mad_decoder_finish(& dec);

		if(data.dump) {
			fclose(data.dump);

			if(killed) {
				unlink(data.tmppath);
			} else {
				int rv;
#ifdef TAGLIB
				TagLib_File *tagme = taglib_file_new_type(data.tmppath, TagLib_File_MPEG);
				if(tagme != NULL) {
					TagLib_Tag *tag = taglib_file_tag(tagme);
					taglib_tag_set_title(tag, value(&track, "title"));
					taglib_tag_set_artist(tag, value(&track, "creator"));
					taglib_tag_set_album(tag, value(&track, "album"));
					taglib_file_save(tagme);
					taglib_file_free(tagme);
				}
#endif
				if(haskey(& rc, "pp-cmd")) {
					const char *ppcmd = value(& rc, "pp-cmd");
					size_t ppcmdlen = strlen(ppcmd);
					char *path = shellescape(data.tmppath);
					assert(path != NULL);
					size_t pathlen = strlen(path);
					char *command = malloc(ppcmdlen + pathlen + 2);
					assert(command != NULL);
					memcpy(command, ppcmd, ppcmdlen);
					command[ppcmdlen] = ' ';
					memcpy(command + ppcmdlen + 1, path, pathlen);
					command[ppcmdlen + 1 + pathlen] = 0;
					run(command);
					free(path);
					free(command);
				}

				rv = rename(data.tmppath, data.finpath);
				if (rv == -1)
					fprintf(stderr, "Can't rename %s to %s\n",
							data.tmppath, data.finpath);
			}

			free(data.tmppath);
			free(data.finpath);
		}
	}
	else
#endif
	{
		pid_t ppid = getppid(), cpid = 0;
		const char * cmd = meta(value(& rc, "extern"), M_SHELLESC, & track);
		FILE * ext = openpipe(cmd, & cpid);
		unsigned char * buf;

		if(!ext) {
			fprintf(stderr, "Failed to execute external player (%s). %s.\n",
					cmd, strerror(errno));
			return 0;
		}

		if(!(buf = calloc(BUFSIZE + 1, sizeof(unsigned char)))) {
			fputs("Couldn't allocate enough memory for input buffer.\n", stderr);
			fclose(ext);
			return 0;
		}

		while(!feof(streamfd)) {
			signed nbyte = fread(buf, sizeof(unsigned char), BUFSIZE, streamfd);

			if(nbyte > 0) {
				fwrite(buf, sizeof(unsigned char), nbyte, ext);
				fflush(ext);
			}

			if(kill(ppid, 0) == -1 && errno == ESRCH)
				break;

			if(killed)
				break;
		}

		free(buf);
		fclose(ext);

		waitpid(cpid, NULL, 0);
	}

	return !0;
}
示例#15
0
void cAudio::run()
{
	lt_info("====================== start decoder thread ================================\n");
	/* libavcodec & friends */
	av_register_all();

	AVCodec *codec;
	AVFormatContext *avfc = NULL;
	AVInputFormat *inp;
	AVFrame *frame;
	uint8_t *inbuf = (uint8_t *)av_malloc(INBUF_SIZE);
	AVPacket avpkt;
	int ret, driver;
	/* libao */
	ao_info *ai;
	// ao_device *adevice;
	// ao_sample_format sformat;
	/* resample */
	SwrContext *swr = NULL;
	uint8_t *obuf = NULL;
	int obuf_sz = 0; /* in samples */
	int obuf_sz_max = 0;
	int o_ch, o_sr; /* output channels and sample rate */
	uint64_t o_layout; /* output channels layout */
	char tmp[64] = "unknown";

	curr_pts = 0;
	av_init_packet(&avpkt);
	inp = av_find_input_format("mpegts");
	AVIOContext *pIOCtx = avio_alloc_context(inbuf, INBUF_SIZE, // internal Buffer and its size
			0,		// bWriteable (1=true,0=false)
			NULL,		// user data; will be passed to our callback functions
			_my_read,	// read callback
			NULL,		// write callback
			NULL);		// seek callback
	avfc = avformat_alloc_context();
	avfc->pb = pIOCtx;
	avfc->iformat = inp;
	avfc->probesize = 188*5;
	thread_started = true;

	if (avformat_open_input(&avfc, NULL, inp, NULL) < 0) {
		lt_info("%s: avformat_open_input() failed.\n", __func__);
		goto out;
	}
	ret = avformat_find_stream_info(avfc, NULL);
	lt_debug("%s: avformat_find_stream_info: %d\n", __func__, ret);
	if (avfc->nb_streams != 1)
	{
		lt_info("%s: nb_streams: %d, should be 1!\n", __func__, avfc->nb_streams);
		goto out;
	}
	if (avfc->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
		lt_info("%s: stream 0 no audio codec? 0x%x\n", __func__, avfc->streams[0]->codec->codec_type);

	c = avfc->streams[0]->codec;
	codec = avcodec_find_decoder(c->codec_id);
	if (!codec) {
		lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(c->codec_id));
		goto out;
	}
	if (avcodec_open2(c, codec, NULL) < 0) {
		lt_info("%s: avcodec_open2() failed\n", __func__);
		goto out;
	}
	frame = av_frame_alloc();
	if (!frame) {
		lt_info("%s: avcodec_alloc_frame failed\n", __func__);
		goto out2;
	}
	/* output sample rate, channels, layout could be set here if necessary */
	o_ch = c->channels;		/* 2 */
	o_sr = c->sample_rate;		/* 48000 */
	o_layout = c->channel_layout;	/* AV_CH_LAYOUT_STEREO */
	if (sformat.channels != o_ch || sformat.rate != o_sr ||
	    sformat.byte_format != AO_FMT_NATIVE || sformat.bits != 16 || adevice == NULL)
	{
		driver = ao_default_driver_id();
		sformat.bits = 16;
		sformat.channels = o_ch;
		sformat.rate = o_sr;
		sformat.byte_format = AO_FMT_NATIVE;
		sformat.matrix = 0;
		if (adevice)
			ao_close(adevice);
		adevice = ao_open_live(driver, &sformat, NULL);
		ai = ao_driver_info(driver);
		lt_info("%s: changed params ch %d srate %d bits %d adevice %p\n",
			__func__, o_ch, o_sr, 16, adevice);;
		lt_info("libao driver: %d name '%s' short '%s' author '%s'\n",
				driver, ai->name, ai->short_name, ai->author);
	}
#if 0
	lt_info(" driver options:");
	for (int i = 0; i < ai->option_count; ++i)
		fprintf(stderr, " %s", ai->options[i]);
	fprintf(stderr, "\n");
#endif
	av_get_sample_fmt_string(tmp, sizeof(tmp), c->sample_fmt);
	lt_info("decoding %s, sample_fmt %d (%s) sample_rate %d channels %d\n",
		 avcodec_get_name(c->codec_id), c->sample_fmt, tmp, c->sample_rate, c->channels);
	swr = swr_alloc_set_opts(swr,
				 o_layout, AV_SAMPLE_FMT_S16, o_sr,			/* output */
				 c->channel_layout, c->sample_fmt, c->sample_rate,	/* input */
				 0, NULL);
	if (! swr) {
		lt_info("could not alloc resample context\n");
		goto out3;
	}
	swr_init(swr);
	while (thread_started) {
		int gotframe = 0;
		if (av_read_frame(avfc, &avpkt) < 0)
			break;
		avcodec_decode_audio4(c, frame, &gotframe, &avpkt);
		if (gotframe && thread_started) {
			int out_linesize;
			obuf_sz = av_rescale_rnd(swr_get_delay(swr, c->sample_rate) +
						 frame->nb_samples, o_sr, c->sample_rate, AV_ROUND_UP);
			if (obuf_sz > obuf_sz_max) {
				lt_info("obuf_sz: %d old: %d\n", obuf_sz, obuf_sz_max);
				av_free(obuf);
				if (av_samples_alloc(&obuf, &out_linesize, o_ch,
							frame->nb_samples, AV_SAMPLE_FMT_S16, 1) < 0) {
					lt_info("av_samples_alloc failed\n");
					av_free_packet(&avpkt);
					break; /* while (thread_started) */
				}
				obuf_sz_max = obuf_sz;
			}
			obuf_sz = swr_convert(swr, &obuf, obuf_sz,
					      (const uint8_t **)frame->extended_data, frame->nb_samples);
			curr_pts = av_frame_get_best_effort_timestamp(frame);
			lt_debug("%s: pts 0x%" PRIx64 " %3f\n", __func__, curr_pts, curr_pts/90000.0);
			int o_buf_sz = av_samples_get_buffer_size(&out_linesize, o_ch,
								  obuf_sz, AV_SAMPLE_FMT_S16, 1);
			ao_play(adevice, (char *)obuf, o_buf_sz);
		}
		av_free_packet(&avpkt);
	}
	// ao_close(adevice); /* can take long :-( */
	av_free(obuf);
	swr_free(&swr);
 out3:
	av_frame_free(&frame);
 out2:
	avcodec_close(c);
	c = NULL;
 out:
	avformat_close_input(&avfc);
	av_free(pIOCtx->buffer);
	av_free(pIOCtx);
	lt_info("======================== end decoder thread ================================\n");
}
示例#16
0
int main(int argc, char **argv) {
    int status = 0;
    struct params par;
    int opt;

    signal(SIGHUP,  interrupt_handler);
    signal(SIGINT,  interrupt_handler);
    signal(SIGQUIT, interrupt_handler);

    ao_initialize();
    driver_id = ao_default_driver_id();
    memset(&current_sample_format, 0, sizeof(current_sample_format));

    if (argc == 1) {
        /* We were invoked with no arguments */
        usage(argv[0]);
        goto done;
    }

    again:

    {
        struct params default_par = DEFAULT_PARAMS;
        memcpy(&par, &default_par, sizeof(par));
    }

    while ((opt = getopt(argc, argv, "-D:F:L:M:S:b:d:f:o:@:hrv")) != -1) {
        switch (opt) {
            case '@':
                if (play_playlist(optarg, &par)) {
                    status = 1;
                    goto done;
                }
                break;
            case 'D':
                par.fade_delay = atof(optarg);
                break;
            case 'F':
                par.fade_time = atof(optarg);
                break;
            case 'L':
                par.loop_count = atoi(optarg);
                break;
            case 'M':
                par.min_time = atof(optarg);
                par.loop_count = -1;
                break;
            case 'S':
                par.stream_index = atoi(optarg);
                break;
            case 'b':
                if (!buffer)
                    buffer_size_kb = atoi(optarg);
                break;
            case 'd':
                driver_id = ao_driver_id(optarg);
                if (driver_id < 0) {
                    fprintf(stderr, "Invalid output driver \"%s\"\n", optarg);
                    status = 1;
                    goto done;
                }
                break;
            case 'f':
                out_filename = optarg;
                break;
            case 'h':
                usage(argv[0]);
                goto done;
            case 'o':
                add_driver_option(optarg);
                break;
            case 'r':
                repeat = 1;
                break;
            case 'v':
                verbose = 1;
                break;
            default:
                goto done;
        }
    }
    argc -= optind;
    argv += optind;

    for (opt = 0; opt < argc; ++opt) {
        if (play_file(argv[opt], &par)) {
            status = 1;
            goto done;
        }
    }

    if (repeat) {
        optind = 0;
        goto again;
    }

    done:

    if (device)
        ao_close(device);
    if (buffer)
        free(buffer);

    ao_free_options(device_options);
    ao_shutdown();

    return status;
}
示例#17
0
文件: player.c 项目: jenikm/pianobar
/*	play aac stream
 *	@param streamed data
 *	@param received bytes
 *	@param extra data (player data)
 *	@return received bytes or less on error
 */
static WaitressCbReturn_t BarPlayerAACCb (void *ptr, size_t size,
		void *stream) {
	const char *data = ptr;
	struct audioPlayer *player = stream;

	if (BarPlayerCheckPauseQuit (player) ||
			!BarPlayerBufferFill (player, data, size)) {
		return WAITRESS_CB_RET_ERR;
	}

	if (player->mode == PLAYER_RECV_DATA) {
		short int *aacDecoded;
		NeAACDecFrameInfo frameInfo;
		size_t i;

		while (player->sampleSizeCurr < player->sampleSizeN &&
				(player->bufferFilled - player->bufferRead) >=
			player->sampleSize[player->sampleSizeCurr]) {
			/* going through this loop can take up to a few seconds =>
			 * allow earlier thread abort */
			if (BarPlayerCheckPauseQuit (player)) {
				return WAITRESS_CB_RET_ERR;
			}

			/* decode frame */
			aacDecoded = NeAACDecDecode(player->aacHandle, &frameInfo,
					&player->buffer[player->bufferRead],
					player->sampleSize[player->sampleSizeCurr]);
			player->bufferRead += player->sampleSize[player->sampleSizeCurr];
			++player->sampleSizeCurr;

			if (frameInfo.error != 0) {
				/* skip this frame, songPlayed will be slightly off if this
				 * happens */
				BarUiMsg (player->settings, MSG_ERR, "Decoding error: %s\n",
						NeAACDecGetErrorMessage (frameInfo.error));
				continue;
			}
			/* assuming data in stsz atom is correct */
			assert (frameInfo.bytesconsumed ==
					player->sampleSize[player->sampleSizeCurr-1]);

			for (i = 0; i < frameInfo.samples; i++) {
				aacDecoded[i] = applyReplayGain (aacDecoded[i], player->scale);
			}
			/* ao_play needs bytes: 1 sample = 16 bits = 2 bytes */
			ao_play (player->audioOutDevice, (char *) aacDecoded,
					frameInfo.samples * 2);
			/* add played frame length to played time, explained below */
			player->songPlayed += (unsigned long long int) frameInfo.samples *
					(unsigned long long int) BAR_PLAYER_MS_TO_S_FACTOR /
					(unsigned long long int) player->samplerate /
					(unsigned long long int) player->channels;
		}
		if (player->sampleSizeCurr >= player->sampleSizeN) {
			/* no more frames, drop data */
			player->bufferRead = player->bufferFilled;
		}
	} else {
		if (player->mode == PLAYER_INITIALIZED) {
			while (player->bufferRead+4 < player->bufferFilled) {
				if (memcmp (player->buffer + player->bufferRead, "esds",
						4) == 0) {
					player->mode = PLAYER_FOUND_ESDS;
					player->bufferRead += 4;
					break;
				}
				player->bufferRead++;
			}
		}
		if (player->mode == PLAYER_FOUND_ESDS) {
			/* FIXME: is this the correct way? */
			/* we're gonna read 10 bytes */
			while (player->bufferRead+1+4+5 < player->bufferFilled) {
				if (memcmp (player->buffer + player->bufferRead,
						"\x05\x80\x80\x80", 4) == 0) {
					ao_sample_format format;
					int audioOutDriver;

					/* +1+4 needs to be replaced by <something>! */
					player->bufferRead += 1+4;
					char err = NeAACDecInit2 (player->aacHandle, player->buffer +
							player->bufferRead, 5, &player->samplerate,
							&player->channels);
					player->bufferRead += 5;
					if (err != 0) {
						BarUiMsg (player->settings, MSG_ERR,
								"Error while initializing audio decoder "
								"(%i)\n", err);
						return WAITRESS_CB_RET_ERR;
					}
					audioOutDriver = ao_default_driver_id();
					memset (&format, 0, sizeof (format));
					format.bits = 16;
					format.channels = player->channels;
					format.rate = player->samplerate;
					format.byte_format = AO_FMT_NATIVE;
					if ((player->audioOutDevice = ao_open_live (audioOutDriver,
							&format, NULL)) == NULL) {
						/* we're not interested in the errno */
						player->aoError = 1;
						BarUiMsg (player->settings, MSG_ERR,
								"Cannot open audio device\n");
						return WAITRESS_CB_RET_ERR;
					}
					player->mode = PLAYER_AUDIO_INITIALIZED;
					break;
				}
				player->bufferRead++;
			}
		}
		if (player->mode == PLAYER_AUDIO_INITIALIZED) {
			while (player->bufferRead+4+8 < player->bufferFilled) {
				if (memcmp (player->buffer + player->bufferRead, "stsz",
						4) == 0) {
					player->mode = PLAYER_FOUND_STSZ;
					player->bufferRead += 4;
					/* skip version and unknown */
					player->bufferRead += 8;
					break;
				}
				player->bufferRead++;
			}
		}
		/* get frame sizes */
		if (player->mode == PLAYER_FOUND_STSZ) {
			while (player->bufferRead+4 < player->bufferFilled) {
				/* how many frames do we have? */
				if (player->sampleSizeN == 0) {
					/* mp4 uses big endian, convert */
					memcpy (&player->sampleSizeN, player->buffer +
							player->bufferRead, sizeof (uint32_t));
					player->sampleSizeN =
							bigToHostEndian32 (player->sampleSizeN);

					player->sampleSize = malloc (player->sampleSizeN *
							sizeof (*player->sampleSize));
					assert (player->sampleSize != NULL);
					player->bufferRead += sizeof (uint32_t);
					player->sampleSizeCurr = 0;
					/* set up song duration (assuming one frame always contains
					 * the same number of samples)
					 * calculation: channels * number of frames * samples per
					 * frame / samplerate */
					/* FIXME: Hard-coded number of samples per frame */
					player->songDuration = (unsigned long long int) player->sampleSizeN *
							4096LL * (unsigned long long int) BAR_PLAYER_MS_TO_S_FACTOR /
							(unsigned long long int) player->samplerate /
							(unsigned long long int) player->channels;
					break;
				} else {
					memcpy (&player->sampleSize[player->sampleSizeCurr],
							player->buffer + player->bufferRead,
							sizeof (uint32_t));
					player->sampleSize[player->sampleSizeCurr] =
							bigToHostEndian32 (
							player->sampleSize[player->sampleSizeCurr]);

					player->sampleSizeCurr++;
					player->bufferRead += sizeof (uint32_t);
				}
				/* all sizes read, nearly ready for data mode */
				if (player->sampleSizeCurr >= player->sampleSizeN) {
					player->mode = PLAYER_SAMPLESIZE_INITIALIZED;
					break;
				}
			}
		}
		/* search for data atom and let the show begin... */
		if (player->mode == PLAYER_SAMPLESIZE_INITIALIZED) {
			while (player->bufferRead+4 < player->bufferFilled) {
				if (memcmp (player->buffer + player->bufferRead, "mdat",
						4) == 0) {
					player->mode = PLAYER_RECV_DATA;
					player->sampleSizeCurr = 0;
					player->bufferRead += 4;
					break;
				}
				player->bufferRead++;
			}
		}
	}

	BarPlayerBufferMove (player);

	return WAITRESS_CB_RET_OK;
}
示例#18
0
文件: client.c 项目: ewenig/libPOLY
// Initialize the libPOLY global state. Return 0 on success, 1 on error.
int poly_init(int bitdepth, int channels, int bitrate, int max_generators, const char *filename)
{
	// Make sure arguments are valid:
	if(!((bitdepth == 8) || (bitdepth == 16) || (bitdepth == 24)))
	{
		DEBUG_MSG("bitdepth not one of 8, 16, 26");
		errno = EINVAL;
		return 1;
	}
	if(!((channels == 1) || (channels == 2)))
	{
		DEBUG_MSG("channels not one of 1, 2");
		errno = EINVAL;
		return 1;
	}
	if(!((bitrate == 44100) || (bitrate == 48000) || (bitrate == 96000)))
	{
		DEBUG_MSG("bitrate not one of 44100, 48000, 96000");
		errno = EINVAL;
		return 1;
	}
	if(max_generators <= 0)
	{
		DEBUG_MSG("max_generators <= 0");
		errno = EINVAL;
		return 1;
	}

	// Initialize libao:
	ao_initialize();
	poly_ao_init = 1;

	poly_playback = 0;
	poly_max_generators = max_generators;
	poly_time = 0;

	int driver;

	// Populate the format struct:
	poly_format = calloc(1, sizeof(*poly_format));
	if(poly_format == NULL)
	{
		DEBUG_MSG("calloc for *poly_format failed");
		errno = ENOMEM;
		return 1;
	}
	poly_format->bits = bitdepth;
	poly_format->channels = channels;
	poly_format->rate = bitrate;
	poly_format->byte_format = AO_FMT_NATIVE;

	// Are we using a sound card?
	if(filename == NULL)
	{
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(__WIN32__) || defined(__WIN64__) || defined(__WINDOWS__)
		driver = ao_default_driver_id();
		if(driver == -1)
		{
			DEBUG_MSG("ao_default_driver_id() failed");
			errno = ENODEV;
			free(poly_format);
			return 1;
		}
#else
		driver = ao_driver_id("alsa");
		if(driver == -1)
		{
			DEBUG_MSG("ao_driver_id() failed");
			errno = ENODEV;
			free(poly_format);
			return 1;
		}
#endif
		poly_card = ao_open_live(driver, poly_format, NULL);
		if(poly_card == NULL)
		{
			switch(errno)
			{
			case AO_ENODRIVER:
				DEBUG_MSG("invalid driver");
				break;
			case AO_ENOTLIVE:
				DEBUG_MSG("file driver passed, live driver expected");
				break;
			case AO_EBADOPTION:
				DEBUG_MSG("invalid libao option, check local libao config");
				break;
			case AO_EOPENDEVICE:
				DEBUG_MSG("can't open device");
				break;
			default:
				DEBUG_MSG("unknown libao error");
				break;
			}
			free(poly_format);
			return 1;
		}
	}
	// We're using an output file:
	else
	{
		driver = ao_driver_id("wav");
		if(driver == -1)
		{
			DEBUG_MSG("libao error, can't open WAV driver");
			errno = ENODEV;
			free(poly_format);
			return 1;
		}
		poly_card = ao_open_file(driver, filename, 1, poly_format, NULL);
		if(poly_card == NULL)
		{
			switch(errno)
			{
			case AO_ENODRIVER:
				DEBUG_MSG("invalid driver");
				break;
			case AO_ENOTFILE:
				DEBUG_MSG("non-file driver passed");
				break;
			case AO_EBADOPTION:
				DEBUG_MSG("invalid libao option, check local libao config");
				break;
			case AO_EOPENFILE:
				DEBUG_MSG("can't open file");
				break;
			default:
				DEBUG_MSG("unknown libao error");
				break;
			}
			free(poly_format);
			return 1;
		}
	}

	poly_generators = calloc(poly_max_generators, sizeof(*poly_generators));

	return 0;
}
示例#19
0
static PyObject*
py_ao_default_driver_id(PyObject *self, PyObject *args)
{
  /* Passed with METH_NOARGS */
  return PyInt_FromLong(ao_default_driver_id());
}
示例#20
0
int parse_cmdline_options (int argc, char **argv,
			   ogg123_options_t *ogg123_opts,
			   file_option_t    *file_opts)
{
  int option_index = 1;
  ao_option *temp_options = NULL;
  ao_option ** current_options = &temp_options;
  ao_info *info;
  int temp_driver_id = -1;
  audio_device_t *current;
  int ret;

  while (-1 != (ret = getopt_long(argc, argv, "b:c::d:f:hl:k:K:o:p:qrRvVx:y:zZ@:",
				  long_options, &option_index))) {

      switch (ret) {
      case 0:
	if(!strcmp(long_options[option_index].name, "audio-buffer")) {
	  ogg123_opts->buffer_size = 1024 * atoi(optarg);
	} else {
	  status_error(_("Internal error parsing command line options.\n"));
	  exit(1);
	}
	break;
      case 'b':
	ogg123_opts->input_buffer_size = atoi(optarg) * 1024;
	if (ogg123_opts->input_buffer_size < MIN_INPUT_BUFFER_SIZE * 1024) {
	  status_error(_("Input buffer size smaller than minimum size of %dkB."),
		       MIN_INPUT_BUFFER_SIZE);
	  ogg123_opts->input_buffer_size = MIN_INPUT_BUFFER_SIZE * 1024;
	}
	break;
	
      case 'c':
	if (optarg) {
	  char *tmp = strdup (optarg);
	  parse_code_t pcode = parse_line(file_opts, tmp);

	  if (pcode != parse_ok)
	    status_error(_("=== Error \"%s\" while parsing config option from command line.\n"
			 "=== Option was: %s\n"),
			 parse_error_string(pcode), optarg);
	  free (tmp);
	}
	else {
	  /* not using the status interface here */
	  fprintf (stdout, _("Available options:\n"));
	  file_options_describe(file_opts, stdout);
	  exit (0);
	}
	break;
	
      case 'd':
	temp_driver_id = ao_driver_id(optarg);
	if (temp_driver_id < 0) {
	    status_error(_("=== No such device %s.\n"), optarg);
	    exit(1);
	}

	current = append_audio_device(ogg123_opts->devices,
				      temp_driver_id, 
				      NULL, NULL);
	if(ogg123_opts->devices == NULL)
	  ogg123_opts->devices = current;
	current_options = &current->options;
	break;
	
      case 'f':
	if (temp_driver_id >= 0) {

	  info = ao_driver_info(temp_driver_id);
	  if (info->type == AO_TYPE_FILE) {
	    free(current->filename);
	    current->filename = strdup(optarg);
	  } else {
	    status_error(_("=== Driver %s is not a file output driver.\n"),
			 info->short_name);
	    exit(1);
	  }
	} else {
	  status_error(_("=== Cannot specify output file without specifying a driver.\n"));
	  exit (1);
	}
	break;

	case 'k':
 	  set_seek_opt(ogg123_opts, optarg);
	  break;
	  
	case 'K':
	  ogg123_opts->endpos = strtotime(optarg);
	  break;
	  
	case 'l':
	  ogg123_opts->delay = atoi(optarg);
	  break;
	  
	case 'o':
	  if (optarg && !add_ao_option(current_options, optarg)) {
	    status_error(_("=== Incorrect option format: %s.\n"), optarg);
	    exit(1);
	  }
	  break;

	case 'h':
	  cmdline_usage();
	  exit(0);
	  break;

	case 'p':
	  ogg123_opts->input_prebuffer = atof (optarg);
	  if (ogg123_opts->input_prebuffer < 0.0f || 
	      ogg123_opts->input_prebuffer > 100.0f) {

	    status_error (_("--- Prebuffer value invalid. Range is 0-100.\n"));
	    ogg123_opts->input_prebuffer = 
	      ogg123_opts->input_prebuffer < 0.0f ? 0.0f : 100.0f;
	  }
	  break;

      case 'q':
	ogg123_opts->verbosity = 0;
	break;
	
      case 'r':
        ogg123_opts->repeat = 1;
	break;

      case 'R':
	ogg123_opts->remote = 1;
	ogg123_opts->verbosity = 0;
	break;

      case 'v':
	ogg123_opts->verbosity++;
	break;
	
      case 'V':
	status_error(_("ogg123 from %s %s"), PACKAGE, VERSION);
	exit(0);
	break;

      case 'x':
	ogg123_opts->nth = atoi(optarg);
	if (ogg123_opts->nth == 0) {
	  status_error(_("--- Cannot play every 0th chunk!\n"));
	  ogg123_opts->nth = 1;
	}
	break;
	  
      case 'y':
	ogg123_opts->ntimes = atoi(optarg);
	if (ogg123_opts->ntimes == 0) {
	  status_error(_("--- Cannot play every chunk 0 times.\n"
		 "--- To do a test decode, use the null output driver.\n"));
	  ogg123_opts->ntimes = 1;
	}
	break;
	
      case 'z':
	ogg123_opts->shuffle = 1;
	break;

      case 'Z':
        ogg123_opts->repeat = ogg123_opts->shuffle = 1;
	break;

      case '@':
	if (playlist_append_from_file(ogg123_opts->playlist, optarg) == 0)
	  status_error(_("--- Cannot open playlist file %s.  Skipped.\n"),
		       optarg);
	break;
		
      case '?':
	break;
	
      default:
	cmdline_usage();
	exit(1);
      }
  }

  /* Sanity check bad option combinations */
  if (ogg123_opts->endpos > 0.0 &&
      ogg123_opts->seekoff > ogg123_opts->endpos) {
    status_error(_("=== Option conflict: End time is before start time.\n"));
    exit(1);
  }


  /* Add last device to device list or use the default device */
  if (temp_driver_id < 0) {

      /* First try config file setting */
      if (ogg123_opts->default_device) {
	  temp_driver_id = ao_driver_id(ogg123_opts->default_device);

	  if (temp_driver_id < 0)
	    status_error(_("--- Driver %s specified in configuration file invalid.\n"),
			 ogg123_opts->default_device);
      }

      /* Then try libao autodetect */
      if (temp_driver_id < 0)
	temp_driver_id = ao_default_driver_id();

      /* Finally, give up */
      if (temp_driver_id < 0) {
	status_error(_("=== Could not load default driver and no driver specified in config file. Exiting.\n"));
	exit(1);
      }

      ogg123_opts->devices = append_audio_device(ogg123_opts->devices,
					     temp_driver_id,
					     temp_options, 
					     NULL);
    }

  /* if verbosity has been altered, add options to drivers... */
  {
    audio_device_t *head = ogg123_opts->devices;
    while (head){
      if(ogg123_opts->verbosity>3)
        ao_append_global_option("debug",NULL);
      if(ogg123_opts->verbosity>2)
        ao_append_option(&(head->options),"verbose",NULL);
      if(ogg123_opts->verbosity==0)
        ao_append_option(&(head->options),"quiet",NULL);
      head = head->next_device;
    }
  }


  return optind;
}