Exemplo n.º 1
0
int decode_vumeter(lua_State *L) {
	u32_t sample_accumulator[2];
	sample_t *ptr;
	size_t samples_until_wrap;
	s16_t sample;
	s32_t sample_sq;
	size_t i, num_samples;

	num_samples = luaL_optinteger(L, 2, VUMETER_DEFAULT_SAMPLE_WINDOW);

	sample_accumulator[0] = 0;
	sample_accumulator[1] = 0;

	decode_audio_lock();

	if (decode_audio->state & DECODE_STATE_RUNNING) {
		ptr = (sample_t *)(void *)(decode_fifo_buf + decode_audio->fifo.rptr);
		samples_until_wrap = BYTES_TO_SAMPLES(fifo_bytes_until_rptr_wrap(&decode_audio->fifo));

		for (i=0; i<num_samples; i++) {
			sample = (*ptr++) >> 24;
			sample_sq = sample * sample;
			sample_accumulator[0] += sample_sq;

			sample = (*ptr++) >> 24;
			sample_sq = sample * sample;
			sample_accumulator[1] += sample_sq;

			samples_until_wrap -= 2;
			if (samples_until_wrap <= 0) {
				ptr = (sample_t *)(void *)decode_fifo_buf;
			}
		}
	}
Exemplo n.º 2
0
static struct ast_frame *g719read(struct ast_filestream *s, int *whennext)
{
	int res;
	/* Send a frame from the file to the appropriate channel */

	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
		if (res)
			ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
		return NULL;
	}
	*whennext = s->fr.samples = BYTES_TO_SAMPLES(res);
	return &s->fr;
}
Exemplo n.º 3
0
static struct ast_frame *siren14read(struct ast_filestream *s, int *whennext)
{
	int res;
	/* Send a frame from the file to the appropriate channel */

	s->fr.frametype = AST_FRAME_VOICE;
	s->fr.subclass.codec = AST_FORMAT_SIREN14;
	s->fr.mallocd = 0;
	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
		if (res)
			ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
		return NULL;
	}
	*whennext = s->fr.samples = BYTES_TO_SAMPLES(res);
	return &s->fr;
}
Exemplo n.º 4
0
static struct ast_frame *g719read(struct ast_filestream *s, int *whennext)
{
	size_t res;

	/* Send a frame from the file to the appropriate channel */
	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
		if (res) {
			ast_log(LOG_WARNING, "Short read of %s data (expected %d bytes, read %zu): %s\n",
					ast_format_get_name(s->fr.subclass.format), s->fr.datalen, res,
					strerror(errno));
		}
		return NULL;
	}
	*whennext = s->fr.samples = BYTES_TO_SAMPLES(res);
	return &s->fr;
}
Exemplo n.º 5
0
/* Called to copy samples to the decode fifo when we are doing
 * a transition - crossfade or fade in. This method applies gain
 * to both the new signal and the one that's already in the fifo.
 */
static void decode_transition_copy_bytes(sample_t *buffer, size_t nbytes) {
	sample_t sample, *sptr;
	int nsamples, s;
	size_t bytes_read;
	fft_fixed in_gain, out_gain;

	ASSERT_AUDIO_LOCKED();

	while (nbytes) {
		bytes_read = SAMPLES_TO_BYTES(transition_sample_step - transition_samples_in_step);

		if (bytes_read > nbytes) {
			bytes_read = nbytes;
		}

		nsamples = BYTES_TO_SAMPLES(bytes_read);

		sptr = (sample_t *)(void *)(decode_fifo_buf + decode_audio->fifo.wptr);

		in_gain = transition_gain;
		out_gain = FIXED_ONE - in_gain;

		if (crossfade_started) {
			for (s=0; s<nsamples * 2; s++) {
				sample = fixed_mul(out_gain, *sptr);
				sample += fixed_mul(in_gain, *buffer++);
				*sptr++ = sample;
			}
		}
		else {
			for (s=0; s<nsamples * 2; s++) {
				*sptr++ = fixed_mul(in_gain, *buffer++);
			}
		}

		fifo_wptr_incby(&decode_audio->fifo, bytes_read);
		nbytes -= bytes_read;

		transition_samples_in_step += nsamples;
		while (transition_samples_in_step >= transition_sample_step) {
			transition_samples_in_step -= transition_sample_step;
			transition_gain += transition_gain_step;
		}
	}
}
Exemplo n.º 6
0
static off_t g719tell(struct ast_filestream *fs)
{
	return BYTES_TO_SAMPLES(ftello(fs->f));
}
Exemplo n.º 7
0
/* All and mighty connection handler. */
static void* rsd_thread(void *thread_data)
{
   connection_t conn;
   void *data = NULL;
   wav_header_t w;
   wav_header_t w_orig;
   int resample = 0;
   int rc, written;
   void *buffer = NULL;
#ifdef HAVE_SAMPLERATE
   SRC_STATE *resample_state = NULL;
#else
   resampler_t *resample_state = NULL;
#endif
   float *resample_buffer = NULL;
   resample_cb_state_t cb_data;

   connection_t *temp_conn = thread_data;
   conn.socket = temp_conn->socket;
   conn.ctl_socket = temp_conn->ctl_socket;
   conn.serv_ptr = 0;
   conn.rate_ratio = 1.0;
   conn.identity[0] = '\0';
   free(temp_conn);

   if ( debug )
      log_printf("Connection accepted, awaiting WAV header data ...\n");

   /* Firstly, get the wave header with stream settings. */
   rc = get_wav_header(conn, &w);
   if ( rc == -1 )
   {
      close(conn.socket);
      close(conn.ctl_socket);
      log_printf("Couldn't read WAV header... Disconnecting.\n");
      pthread_exit(NULL);
   }
   memcpy(&w_orig, &w, sizeof(wav_header_t));

   if ( resample_freq > 0 && resample_freq != (int)w.sampleRate )
   {
      w.sampleRate = resample_freq;
      w.bitsPerSample = w_orig.bitsPerSample == 32 ? 32 : 16;
      if (w_orig.bitsPerSample == 32)
         w.rsd_format = (is_little_endian()) ? RSD_S32_LE : RSD_S32_BE;
      else
         w.rsd_format = (is_little_endian()) ? RSD_S16_LE : RSD_S16_BE;
      resample = 1;
      conn.rate_ratio = (float)w.sampleRate * w.bitsPerSample / ((float)w_orig.sampleRate * w_orig.bitsPerSample);
   }

   if ( debug )
   {
      log_printf("Successfully got WAV header ...\n");
      pheader(&w_orig);
      if ( resample )
      {
         log_printf("Resamples to:\n");
         pheader(&w);
      }
   }

   if ( debug )
      log_printf("Initializing %s ...\n", backend->backend);

   /* Sets up backend */
   if ( backend->init(&data) < 0 )
   {
      log_printf("Failed to initialize %s ...\n", backend->backend);
      goto rsd_exit;
   }

   /* Opens device with settings. */
   if ( backend->open(data, &w) < 0 )
   {
      log_printf("Failed to open audio driver ...\n");
      goto rsd_exit;
   }

   backend_info_t backend_info; 
   memset(&backend_info, 0, sizeof(backend_info));
   backend->get_backend_info(data, &backend_info);
   if ( backend_info.chunk_size == 0 )
   {
      log_printf("Couldn't get backend info ...\n");
      goto rsd_exit;
   }

   if ( backend_info.resample )
   {
      resample = 1;
      w.sampleRate = w.sampleRate * backend_info.ratio;
      conn.rate_ratio = backend_info.ratio;

      w.bitsPerSample = w_orig.bitsPerSample == 32 ? 32 : 16;
      if (w_orig.bitsPerSample == 32)
         w.rsd_format = (is_little_endian()) ? RSD_S32_LE : RSD_S32_BE;
      else
         w.rsd_format = (is_little_endian()) ? RSD_S16_LE : RSD_S16_BE;
   }

   size_t size = backend_info.chunk_size;
   size_t read_size = size;

   size_t buffer_size = (read_size > size) ? read_size : size;
   buffer = malloc(buffer_size);
   if ( buffer == NULL )
   {
      log_printf("Could not allocate memory for buffer.");
      goto rsd_exit;
   }

   if ( resample )
   {
      resample_buffer = malloc(BYTES_TO_SAMPLES(buffer_size, w.rsd_format) * sizeof(float));
      if ( resample_buffer == NULL )
      {
         log_printf("Could not allocate memory for buffer.");
         goto rsd_exit;
      }

      cb_data.format = w_orig.rsd_format;
      cb_data.data = data;
      cb_data.conn = &conn;
      cb_data.framesize = w_orig.numChannels * rsnd_format_to_bytes(w_orig.rsd_format);

#ifdef HAVE_SAMPLERATE
      int err;
      resample_state = src_callback_new(resample_callback, src_converter, w.numChannels, &err, &cb_data);
#else
      resample_state = resampler_new(resample_callback, (float)w.sampleRate/w_orig.sampleRate, w.numChannels, &cb_data);
#endif
      if ( resample_state == NULL )
      {
         log_printf("Could not initialize resampler.");
         goto rsd_exit;
      }
   }

#define MAX_TCP_BUFSIZ (1 << 14)

   // We only bother with setting buffer size if we're doing TCP.
   if ( rsd_conn_type == RSD_CONN_TCP )
   {
      int flag = 1;
      int bufsiz = backend_info.chunk_size * 32;
      if (bufsiz > MAX_TCP_BUFSIZ)
         bufsiz = MAX_TCP_BUFSIZ;

      setsockopt(conn.socket, SOL_SOCKET, SO_RCVBUF, CONST_CAST &bufsiz, sizeof(int));

      if ( conn.ctl_socket )
      {
         setsockopt(conn.ctl_socket, SOL_SOCKET, SO_RCVBUF, CONST_CAST &bufsiz, sizeof(int));
         setsockopt(conn.ctl_socket, SOL_SOCKET, SO_SNDBUF, CONST_CAST &bufsiz, sizeof(int));
         setsockopt(conn.ctl_socket, IPPROTO_TCP, TCP_NODELAY, CONST_CAST &flag, sizeof(int));
      }

      setsockopt(conn.socket, IPPROTO_TCP, TCP_NODELAY, CONST_CAST &flag, sizeof(int));
   }

   /* Now we can send backend info to client. */
   if ( send_backend_info(conn, &backend_info) < 0 )
   {
      log_printf("Failed to send backend info ...\n");
      goto rsd_exit;
   }

   if ( debug )
      log_printf("Initializing of %s successful ...\n", backend->backend);

   if ( debug )
   {
      if ( resample )
      {
         log_printf("Resampling active. %d Hz --> %d Hz ", (int)w_orig.sampleRate, (int)w.sampleRate);
#ifdef HAVE_SAMPLERATE
         log_printf("(libsamplerate)\n");
#else
         log_printf("(internal quadratic resampler)\n");
#endif
      }
   }

   /* Recieve data, write to sound card. Rinse, repeat :') */
   for(;;)
   {
      if ( strlen(conn.identity) > 0 && verbose )
      {
         log_printf(" :: %s\n", conn.identity);
         conn.identity[0] = '\0';
      }

      if ( resample )
      {
#ifdef HAVE_SAMPLERATE
         rc = src_callback_read(resample_state, (double)w.sampleRate/(double)w_orig.sampleRate, BYTES_TO_SAMPLES(size, w.rsd_format)/w.numChannels, resample_buffer);
         if (rsnd_format_to_bytes(w.rsd_format) == 4)
            src_float_to_int_array(resample_buffer, buffer, BYTES_TO_SAMPLES(size, w.rsd_format));
         else
            src_float_to_short_array(resample_buffer, buffer, BYTES_TO_SAMPLES(size, w.rsd_format));
#else
         rc = resampler_cb_read(resample_state, BYTES_TO_SAMPLES(size, w.rsd_format)/w.numChannels, resample_buffer);
         if (rsnd_format_to_bytes(w.rsd_format) == 4)
            resampler_float_to_s32(buffer, resample_buffer, BYTES_TO_SAMPLES(size, w.rsd_format));
         else
            resampler_float_to_s16(buffer, resample_buffer, BYTES_TO_SAMPLES(size, w.rsd_format));
#endif
      }
      else
         rc = receive_data(data, &conn, buffer, read_size);

      if ( rc <= 0 )
      {
         if ( debug )
            log_printf("Client closed connection.\n");
         goto rsd_exit;
      }

      for ( written = 0; written < (int)size; )
      {
         rc = backend->write(data, (const char*)buffer + written, size - written);
         if ( rc == 0 )
            goto rsd_exit;

         written += rc;
      }
   }

   /* Cleanup */
rsd_exit:
   if ( debug )
      log_printf("Closed connection.\n\n");
#ifdef _WIN32
#undef close
#endif
   backend->close(data);
#ifdef _WIN32
#define close(x) closesocket(x)
#endif
   free(buffer);
   close(conn.socket);
   if (conn.ctl_socket)
      close(conn.ctl_socket);

   if (resample_state)
   {
#ifdef HAVE_SAMPLERATE
      src_delete(resample_state);
#else
      resampler_free(resample_state);
#endif
   }
   free(resample_buffer);
   pthread_exit(NULL);
}