| 77 | } |
| 78 | |
| 79 | size_t |
| 80 | PCMMixerDataSource::GetData(int16_t *buffer, size_t n) |
| 81 | { |
| 82 | size_t copied_count = 0; |
| 83 | |
| 84 | PCMDataSource *sources_to_remove[MAX_MIXER_SOURCES_COUNT]; |
| 85 | unsigned sources_to_remove_count = 0; |
| 86 | |
| 87 | const std::lock_guard protect{lock}; |
| 88 | |
| 89 | for (unsigned i = 0; i < MAX_MIXER_SOURCES_COUNT; ++i) { |
| 90 | PCMDataSource *source = sources[i]; |
| 91 | if (nullptr != source) { |
| 92 | bool do_byte_swap = ::IsBigEndian() != source->IsBigEndian(); |
| 93 | if (0 == copied_count) { |
| 94 | copied_count = source->GetData(buffer, n); |
| 95 | if (0 == copied_count) { |
| 96 | sources_to_remove[sources_to_remove_count++] = source; |
| 97 | } else { |
| 98 | if (do_byte_swap) |
| 99 | ByteSwapAndLowerVolume(buffer, copied_count, vol_percent); |
| 100 | else |
| 101 | LowerVolume(buffer, copied_count, vol_percent); |
| 102 | } |
| 103 | } else { |
| 104 | int16_t temp_buffer[1024]; |
| 105 | size_t current_src_copied_count = 0; |
| 106 | bool current_src_end = false; |
| 107 | while (!current_src_end && (current_src_copied_count < copied_count)) { |
| 108 | size_t bytes_to_read = std::min(copied_count - current_src_copied_count, |
| 109 | ARRAY_SIZE(temp_buffer)); |
| 110 | size_t iteration_read_count = |
| 111 | source->GetData(temp_buffer, bytes_to_read); |
| 112 | if (do_byte_swap) |
| 113 | ByteSwapAndMixPCM(buffer + current_src_copied_count, temp_buffer, |
| 114 | iteration_read_count, vol_percent); |
| 115 | else |
| 116 | MixPCM(buffer + current_src_copied_count, temp_buffer, |
| 117 | iteration_read_count, vol_percent); |
| 118 | current_src_copied_count += iteration_read_count; |
| 119 | current_src_end = (iteration_read_count < bytes_to_read); |
| 120 | } |
| 121 | if (!current_src_end && (copied_count < n)) { |
| 122 | size_t bytes_to_read = n - copied_count; |
| 123 | size_t rest_read_count = |
| 124 | source->GetData(buffer + copied_count, bytes_to_read); |
| 125 | if (do_byte_swap) |
| 126 | ByteSwapAndLowerVolume(buffer + copied_count, rest_read_count, |
| 127 | vol_percent); |
| 128 | else |
| 129 | LowerVolume(buffer + copied_count, rest_read_count, |
| 130 | vol_percent); |
| 131 | copied_count += rest_read_count; |
| 132 | current_src_end = (rest_read_count < bytes_to_read); |
| 133 | } |
| 134 | if (current_src_end) { |
| 135 | sources_to_remove[sources_to_remove_count++] = source; |
| 136 | } |
no test coverage detected