AudioInterfaces.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (c) 2011 Nokia Corporation.
  3. */
  4. /**
  5. *
  6. * GF::GA General interfaces
  7. *
  8. */
  9. #include <memory.h>
  10. #include "AudioInterfaces.h"
  11. //#include <QDebug>
  12. using namespace GF;
  13. /**
  14. * AudioSource
  15. * common functionality
  16. *
  17. */
  18. AudioSourceItem::AudioSourceItem(IAudioSource *s) {
  19. m_currentAudioSource = s;
  20. m_next = 0;
  21. };
  22. AudioSourceItem::~AudioSourceItem() {
  23. delete m_currentAudioSource;
  24. };
  25. /**
  26. * AudioMixer
  27. *
  28. */
  29. AudioMixer::AudioMixer() {
  30. m_sourceList = 0;
  31. m_mixingBuffer = 0;
  32. m_mixingBufferLength = 0;
  33. m_fixedGeneralVolume = 4096;
  34. };
  35. AudioMixer::~AudioMixer() {
  36. destroyList();
  37. if (m_mixingBuffer) {
  38. delete [] m_mixingBuffer;
  39. m_mixingBuffer = 0;
  40. };
  41. };
  42. void AudioMixer::destroyList() {
  43. AudioSourceItem *l = m_sourceList;
  44. while (l) {
  45. AudioSourceItem *n = l->m_next;
  46. delete l;
  47. l = n;
  48. };
  49. m_sourceList = 0;
  50. };
  51. IAudioSource* AudioMixer::addAudioSource( IAudioSource *source ) {
  52. AudioSourceItem *item = new AudioSourceItem(source);
  53. item->m_next = 0;
  54. if (m_sourceList) {
  55. AudioSourceItem *l = m_sourceList;
  56. while (l->m_next) l = l->m_next;
  57. l->m_next = item;
  58. } else m_sourceList = item;
  59. return source;
  60. };
  61. bool AudioMixer::removeAudioSource( IAudioSource *source ) {
  62. // TODO: Implement
  63. return true;
  64. };
  65. void AudioMixer::setGeneralVolume( float vol ) {
  66. m_fixedGeneralVolume = (4096.0f*vol);
  67. };
  68. int AudioMixer::pullAudio( AUDIO_SAMPLE_TYPE *target, int sampleCount ) {
  69. //qDebug() << "AudioMixer::pullAudio" << sampleCount;
  70. if (!m_sourceList) return 0;
  71. if (m_mixingBufferLength< sampleCount) {
  72. if (m_mixingBuffer) delete [] m_mixingBuffer;
  73. m_mixingBufferLength = sampleCount;
  74. m_mixingBuffer = new AUDIO_SAMPLE_TYPE[ m_mixingBufferLength ];
  75. };
  76. memset( target, 0, sizeof( AUDIO_SAMPLE_TYPE ) * sampleCount );
  77. AUDIO_SAMPLE_TYPE *t;
  78. AUDIO_SAMPLE_TYPE *t_target;
  79. AUDIO_SAMPLE_TYPE *s;
  80. AudioSourceItem *prev = 0;
  81. AudioSourceItem *l = m_sourceList;
  82. while (l) {
  83. AudioSourceItem *next = l->m_next;
  84. // process l
  85. int mixed = l->m_currentAudioSource->pullAudio( m_mixingBuffer, sampleCount );
  86. if (mixed>0) {
  87. // mix to main..
  88. t = target;
  89. t_target = t+mixed;
  90. s = m_mixingBuffer;
  91. while (t!=t_target) {
  92. // WARNING: Won't work when the sample type is unsigned int
  93. *t +=(((*s)*m_fixedGeneralVolume)>>12);
  94. t++;
  95. s++;
  96. };
  97. };
  98. // autodestroy
  99. if (l->m_currentAudioSource->canBeDestroyed() == true) { // NOTE, IS UNDER TESTING,... MIGHT CAUSE UNPREDICTABLE CRASHING WITH SOME USE CASES!!!
  100. if (!prev)
  101. m_sourceList = next;
  102. else prev->m_next = next;
  103. delete l;
  104. l = 0;
  105. }
  106. else {
  107. // must only happen when l is NOT destroyed
  108. prev = l;
  109. }
  110. l = next;
  111. };
  112. return sampleCount;
  113. };