You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
4.1KB

  1. /*
  2. * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include "Util/logger.h"
  11. #include "AudioSRC.h"
  12. #include "SDLAudioDevice.h"
  13. using namespace std;
  14. using namespace toolkit;
  15. AudioSRC::AudioSRC(AudioSRCDelegate *del) {
  16. _delegate = del;
  17. }
  18. AudioSRC::~AudioSRC() {}
  19. void AudioSRC::setOutputAudioConfig(const SDL_AudioSpec &cfg) {
  20. int freq = _delegate->getPCMSampleRate();
  21. int format = _delegate->getPCMFormat();
  22. int channels = _delegate->getPCMChannel();
  23. if (-1 == SDL_BuildAudioCVT(&_audio_cvt, format, channels, freq, cfg.format, cfg.channels, cfg.freq)) {
  24. throw std::runtime_error("the format conversion is not supported");
  25. }
  26. InfoL << "audio cvt origin format, freq:" << freq << ", format:" << hex << format << dec << ", channels:" << channels;
  27. InfoL << "audio cvt info, "
  28. << "needed:" << (int)_audio_cvt.needed
  29. << ", src_format:" << hex << (SDL_AudioFormat)_audio_cvt.src_format
  30. << ", dst_format:" << (SDL_AudioFormat)_audio_cvt.dst_format << dec
  31. << ", rate_incr:" << (double)_audio_cvt.rate_incr
  32. << ", len_mult:" << (int)_audio_cvt.len_mult
  33. << ", len_ratio:" << (double)_audio_cvt.len_ratio;
  34. }
  35. void AudioSRC::setEnableMix(bool flag) {
  36. _enabled = flag;
  37. }
  38. int AudioSRC::getPCMData(char *buf, int size) {
  39. if (!_enabled) {
  40. return 0;
  41. }
  42. if (!_audio_cvt.needed) {
  43. //获取原始数据,不需要频率转换
  44. return _delegate->getPCMData(buf, size);
  45. }
  46. //对应的未转换前pcm的长度
  47. auto original_size = (int) (size / _audio_cvt.len_ratio);
  48. if (original_size % 4 != 0) {
  49. //必须为4byte的整数(双通道16bit一个采样就4个字节)
  50. original_size = 4 * (original_size / 4) + 4;
  51. }
  52. //需要准备这么长的buf用于重采样
  53. if ((int) (original_size * _audio_cvt.len_mult) != _buf_size) {
  54. _buf_size = original_size * _audio_cvt.len_mult;
  55. _buf.reset(new char[_buf_size], [](char *ptr) {
  56. delete[] ptr;
  57. });
  58. InfoL << "origin pcm buffer size is:" << original_size << ", target pcm buffer size is:" << size;
  59. }
  60. auto origin_size = _delegate->getPCMData(_buf.get(), original_size );
  61. if (!origin_size) {
  62. //获取数据失败
  63. TraceL << "get empty pcm data";
  64. return 0;
  65. }
  66. _audio_cvt.buf = (Uint8 *) _buf.get();
  67. _audio_cvt.len = origin_size;
  68. if (0 != SDL_ConvertAudio(&_audio_cvt)) {
  69. WarnL << "SDL_ConvertAudio failed!";
  70. _audio_cvt.len_cvt = 0;
  71. }
  72. if (_audio_cvt.len_cvt) {
  73. _target_buf.append(_buf.get(), _audio_cvt.len_cvt);
  74. }
  75. if (_target_buf.size() < (size_t)size) {
  76. return 0;
  77. }
  78. memcpy(buf, _target_buf.data(), size);
  79. _target_buf.erase(0, size);
  80. return size;
  81. }
  82. ////////////////////////////////////////////////////////////////////////
  83. AudioPlayer::AudioPlayer() : AudioSRC(this) {
  84. _device = SDLAudioDevice::Instance().shared_from_this();
  85. }
  86. AudioPlayer::~AudioPlayer() {
  87. _device->delChannel(this);
  88. }
  89. void AudioPlayer::setup(int sample_rate, int channel, SDL_AudioFormat format) {
  90. _sample_rate = sample_rate;
  91. _channel = channel;
  92. _format = format;
  93. _device->addChannel(this);
  94. }
  95. SDL_AudioFormat AudioPlayer::getPCMFormat() {
  96. return _format;
  97. }
  98. int AudioPlayer::getPCMSampleRate() {
  99. return _sample_rate;
  100. }
  101. int AudioPlayer::getPCMChannel() {
  102. return _channel;
  103. }
  104. int AudioPlayer::getPCMData(char *buf, int size) {
  105. lock_guard<mutex> lck(_mtx);
  106. if (_buffer.size() < (size_t)size) {
  107. return 0;
  108. }
  109. memcpy(buf, _buffer.data(), size);
  110. _buffer.erase(0, size);
  111. return size;
  112. }
  113. void AudioPlayer::playPCM(const char *data, size_t size) {
  114. lock_guard<mutex> lck(_mtx);
  115. _buffer.append(data, size);
  116. }