⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio_sdl.cpp

📁 完整的RTP RTSP代码库
💻 CPP
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000-2005.  All Rights Reserved. *  * Contributor(s):  *              Bill May        wmay@cisco.com *//* * audio_sdl.cpp provides the interface between the CBufferAudioSync * class and our version of the SDL audio APIs. */#include <stdlib.h>#include <string.h>#include "player_session.h"#include "audio_sdl.h"#include "player_util.h"#include "our_config_file.h"//#define TEST_MONO_TO_STEREO 1#ifdef _WIN32DEFINE_MESSAGE_MACRO(audio_message, "audiosdl")#else#define audio_message(loglevel, fmt...) message(loglevel, "audiosdl", fmt)#endif/* * c routine to call into the AudioSync class callback */static void c_audio_callback (void *userdata, Uint8 *stream, int len){  CSDLAudioSync *a = (CSDLAudioSync *)userdata;  a->audio_callback(stream, len);}void CSDLAudioSync::audio_callback(Uint8 *stream, int len){  uint32_t latency;  uint64_t our_time;    our_time = get_time_of_day_usec();  if (m_use_SDL_delay != 0) {    latency = SDL_AUDIODELAY();	if (latency < 0) latency = 0;  } else {    latency = 0;  }  audio_buffer_callback((uint8_t *)stream, len, latency, our_time);}/* * Create an CSDLAudioSync for a session.  Don't alloc any buffers until * config is called by codec */CSDLAudioSync::CSDLAudioSync (CPlayerSession *psptr, int volume) :  CBufferAudioSync(psptr, volume){  SDL_AUDIOINIT(getenv("SDL_AUDIODRIVER"));  m_volume = (volume * SDL_MIX_MAXVOLUME)/100;}/* * Close out audio sync - stop and disconnect from SDL */CSDLAudioSync::~CSDLAudioSync (void){  SDL_PAUSEAUDIO(1);  SDL_CLOSEAUDIO();}// Sync task api - initialize the sucker.// May need to check out non-standard frequencies, see about conversion.// returns 1 for initialized, -1 for errorint CSDLAudioSync::InitializeHardware (void) {  uint32_t bytes_per_sample;  SDL_AudioSpec wanted;    memset(&wanted, 0, sizeof(wanted));  wanted.freq = m_freq;  wanted.channels = m_channels;  // bytes per sample is the # of bytes for the output buffer  bytes_per_sample = 2;  switch (m_decode_format) {  case AUDIO_FMT_U8: wanted.format = AUDIO_U8; bytes_per_sample = 1; break;  case AUDIO_FMT_S8: wanted.format = AUDIO_S8; bytes_per_sample = 1; break;  case AUDIO_FMT_U16LSB: wanted.format = AUDIO_U16LSB; break;  case AUDIO_FMT_U16MSB: wanted.format = AUDIO_U16MSB; break;  case AUDIO_FMT_S16LSB: wanted.format = AUDIO_S16LSB; break;  case AUDIO_FMT_S16MSB: wanted.format = AUDIO_S16MSB; break;  case AUDIO_FMT_U16: wanted.format = AUDIO_U16SYS; break;  case AUDIO_FMT_S16: wanted.format = AUDIO_S16SYS; break;  case AUDIO_FMT_FLOAT: wanted.format = AUDIO_S16SYS; break;  case AUDIO_FMT_HW_AC3:     wanted.format = AUDIO_FORMAT_HW_AC3;     bytes_per_sample = 1;    break;  }  uint32_t sample_size;  sample_size = m_samples_per_frame * m_channels;#ifndef _WIN32  uint32_t ix;  for (ix = 2; ix <= 0x8000; ix <<= 1) {    if ((sample_size & ~(ix - 1)) == 0) {      break;    }  }  ix >>= 1;  audio_message(LOG_DEBUG, "Sample size is %d", ix);  sample_size = ix;#else  sample_size = 4096;#endif  if (config.get_config_value(CONFIG_LIMIT_AUDIO_SDL_BUFFER) > 1) {    sample_size = MAX(config.get_config_value(CONFIG_LIMIT_AUDIO_SDL_BUFFER),		      sample_size);  } else {    if (config.get_config_value(CONFIG_LIMIT_AUDIO_SDL_BUFFER) > 0 &&	sample_size > 4096)       sample_size = 4096;    if (sample_size < m_freq / 10)       sample_size = 4096;        while (sample_size * m_bytes_per_sample_input > m_sample_buffer_size / 4) {      sample_size /= 2;    }  }  wanted.samples = sample_size;  wanted.callback = c_audio_callback;  wanted.userdata = this;#if 1  audio_message(LOG_INFO, 		"requested f %d chan %d format %x samples %d",		wanted.freq,		wanted.channels,		wanted.format,		wanted.samples);#endif  int ret = SDL_OPENAUDIO(&wanted, &m_obtained);  if (ret < 0) {    audio_message(LOG_ERR, "Couldn't open audio %d channels - %s",		  wanted.channels, SDL_GetError());    if (wanted.channels > 2) {      wanted.channels = 2;      ret = SDL_OPENAUDIO(&wanted, &m_obtained);    }    if (ret < 0) {      audio_message(LOG_CRIT, "Couldn't open audio, %s", SDL_GetError());      return (-1);    }  }  char buffer[128];  if (SDL_AUDIODRIVERNAME(buffer, sizeof(buffer)) == NULL) {    strcpy(buffer, "no audio driver");  }  audio_message(LOG_INFO, "got f %d chan %d format %x samples %d size %u %s",		m_obtained.freq,		m_obtained.channels,		m_obtained.format,		m_obtained.samples,		m_obtained.size,		buffer);#ifdef TEST_MONO_TO_STEREO#define CHECK_SDL_CHANS_RETURNED  TRUE#define OBTAINED_CHANS  2#else#define CHECK_SDL_CHANS_RETURNED m_obtained.channels != m_channels#define OBTAINED_CHANS  m_obtained.channels#endif  bool need_convert = false;  if (CHECK_SDL_CHANS_RETURNED) {    SDL_CLOSEAUDIO();    wanted.channels = OBTAINED_CHANS;    wanted.format = AUDIO_S16SYS; // we're converting, so always choose    m_bytes_per_sample_output = sizeof(int16_t) * wanted.channels;        ret = SDL_OPENAUDIO(&wanted, &m_obtained);    audio_message(LOG_INFO, 		  "requested f %d chan %d format %x samples %d",		  wanted.freq,		  wanted.channels,		  wanted.format,		  wanted.samples);    if (ret < 0) {      audio_message(LOG_CRIT, "Couldn't reopen audio, %s", SDL_GetError());      return (-1);    }    audio_message(LOG_INFO, "got f %d chan %d format %x samples %d size %u %s",		  m_obtained.freq,		  m_obtained.channels,		  m_obtained.format,		  m_obtained.samples,		  m_obtained.size,		  buffer);    need_convert = true;  } else {    m_bytes_per_sample_output = m_obtained.channels * bytes_per_sample;  }  m_got_channels = m_obtained.channels;  m_output_buffer_size_bytes = m_obtained.size;  if (m_decode_format == AUDIO_FMT_FLOAT || need_convert) {    audio_message(LOG_DEBUG, "convert buffer size is %d", m_obtained.size);    audio_convert_init(m_obtained.size, m_obtained.samples);  }  m_use_SDL_delay = SDL_HAS_AUDIO_DELAY();  if (m_use_SDL_delay)    audio_message(LOG_NOTICE, "Using delay measurement from SDL");  return 1; // check again pretty soon...}void CSDLAudioSync::StartHardware (void) {  SDL_PAUSEAUDIO(0);}void CSDLAudioSync::StopHardware (void) {  SDL_PAUSEAUDIO(1);}void CSDLAudioSync::CopyBytesToHardware (uint8_t *from,					 uint8_t *to, 					 uint32_t bytes){  SDL_MIXAUDIO(/*(unsigned char *)*/to, 		   /*(const unsigned char *)*/from,		   bytes, 		   m_volume);}void CSDLAudioSync::set_volume (int volume){  m_volume = (volume * SDL_MIX_MAXVOLUME)/100;}/* * These are the function interfaces from the plugins to the  * CSDLAudioSync class functions */static void c_audio_config (void *ifptr, int freq, 			    int chans, audio_format_t format, 			    uint32_t max_samples){  ((CSDLAudioSync *)ifptr)->set_config(freq,				       chans,				       format,				       max_samples);}static uint8_t *c_get_audio_buffer (void *ifptr,				    uint32_t freq_ts,				    uint64_t ts){  return ((CSDLAudioSync *)ifptr)->get_audio_buffer(freq_ts, ts);}static void c_filled_audio_buffer (void *ifptr){  ((CSDLAudioSync *)ifptr)->filled_audio_buffer();}static void c_load_audio_buffer (void *ifptr, 				 const uint8_t *from, 				 uint32_t bytes, 				 uint32_t freq_ts,				 uint64_t ts){  ((CSDLAudioSync *)ifptr)->load_audio_buffer(from,					      bytes,					      freq_ts, 					      ts);}  static audio_vft_t audio_vft = {  message,  c_audio_config,  c_get_audio_buffer,  c_filled_audio_buffer,  c_load_audio_buffer,  NULL,};CAudioSync *create_audio_sync (CPlayerSession *psptr){  return new CSDLAudioSync(psptr, psptr->get_audio_volume());}audio_vft_t *get_audio_vft (void){  audio_vft.pConfig = &config;  return &audio_vft;}int do_we_have_audio (void) {  char buffer[80];  if (SDL_AUDIOINIT(getenv("SDL_AUDIODRIVER")) < 0) {    player_debug_message("Can't initialize SDL audio");    return (0);  }   if (SDL_AUDIODRIVERNAME(buffer, sizeof(buffer)) == NULL) {    player_debug_message("No buffer name");    return (0);  }  //  Our_SDL_CloseAudio(); - wmay - don't know why commented out -   // causes memleak if PlayAudio is 0.  return (1);}/* end audio_sdl.cpp */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -