예제 #1
0
void audio_send_tone(wave_type_t type, unsigned int hz) {
  unsigned* waveform;
  if (type == WAVE_TRIANGLE) {
    waveform = waveform_triangle;
  } else if (type == WAVE_SINE) {
    waveform = waveform_sine;
  } else if (type == WAVE_SAW) {
    waveform = waveform_saw;
  } else {
    waveform = waveform_square;
  }
  
  if (audio_set_clock(hz)) {
    // Start the clock
    // enable (ENAB) + oscillator 
    // raspbian has this as plla
    *(clk + BCM2835_PWMCLK_CNTL) = PM_PASSWORD |
      BCM2835_CM_ENAB |
      BCM2835_CM_OSCILLATOR;
    
    delay_us(2000);
    
    // disable PWM
    *(pwm + BCM2835_PWM_CONTROL) = 0;
    
    delay_us(2000);
    
    // We are dividing each "step" of the sinusoid into 128
    // pulse slots.
    *(pwm+BCM2835_PWM0_RANGE) = 0x80;
    *(pwm+BCM2835_PWM1_RANGE) = 0x80;

    // Re-enable PWM
    *(pwm+BCM2835_PWM_CONTROL) =
      BCM2835_PWM1_USEFIFO | 
      BCM2835_PWM1_ENABLE | 
      BCM2835_PWM0_USEFIFO | 
      BCM2835_PWM0_ENABLE |
      1 << 6; // Clear the FIFO of any old data
    
    delay_us(2000);

    int i = 0;
    
    while(1) {
      int status =  *(pwm + BCM2835_PWM_STATUS);
      
      if (!(status & BCM2835_FULL1)) {
        *(pwm+BCM2835_PWM_FIFO) = waveform[i];
        i++;
        i = i % 64;
      }
      if ((status & ERRORMASK)) {
        *(pwm+BCM2835_PWM_STATUS) = ERRORMASK;
      } 
    }
  }
}
예제 #2
0
파일: audio.c 프로젝트: dreamcat4/showtime
static void *
dummy_audio_thread(void *aux)
{
  audio_decoder_t *ad = aux;
  media_pipe_t *mp = ad->ad_mp;
  media_queue_t *mq = &mp->mp_audio;
  media_buf_t *mb;
  int hold = 0;
  int run = 1;
  int64_t rt = 0;
  int64_t base = AV_NOPTS_VALUE;


  hts_mutex_lock(&mp->mp_mutex);

  while(run) {

    if((mb = TAILQ_FIRST(&mq->mq_q)) == NULL) {
      hts_cond_wait(&mq->mq_avail, &mp->mp_mutex);
      continue;
    }

    if(mb->mb_data_type == MB_AUDIO && hold && mb->mb_skip == 0) {
      hts_cond_wait(&mq->mq_avail, &mp->mp_mutex);
      continue;
    }

    TAILQ_REMOVE(&mq->mq_q, mb, mb_link);
    mq->mq_packets_current--;
    mp->mp_buffer_current -= mb->mb_size;
    mq_update_stats(mp, mq);
    hts_cond_signal(&mp->mp_backpressure);
    hts_mutex_unlock(&mp->mp_mutex);

    switch(mb->mb_data_type) {
    case MB_CTRL_EXIT:
      run = 0;
      break;

    case MB_CTRL_PAUSE:
      hold = 1;
      break;

    case MB_CTRL_PLAY:
      hold = 0;
      base = AV_NOPTS_VALUE;
      break;

    case MB_FLUSH:
      base = AV_NOPTS_VALUE;
      break;

    case MB_AUDIO:
      if(mb->mb_skip || mb->mb_stream != mq->mq_stream) 
	break;
      if(mb->mb_pts != AV_NOPTS_VALUE) {
        audio_set_clock(mp, mb->mb_pts, 0, mb->mb_epoch);

        if(base == AV_NOPTS_VALUE) {
          base = mb->mb_pts;
          rt = showtime_get_ts();
        } else {
          int64_t d = mb->mb_pts - base;
          if(d > 0) {
            int sleeptime = rt + d - showtime_get_ts();
	    if(sleeptime > 0)
	      usleep(sleeptime);
          }
        }
      }
      break;

    default:
      abort();
    }
    hts_mutex_lock(&mp->mp_mutex);
    media_buf_free_locked(mp, mb);
  }
  hts_mutex_unlock(&mp->mp_mutex);
  return NULL;
}