mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	audio_core: Fix FDK AAC decoding. (#6530)
This commit is contained in:
		
							parent
							
								
									dc39eac916
								
							
						
					
					
						commit
						0768bd8ce0
					
				
					 2 changed files with 29 additions and 32 deletions
				
			
		|  | @ -187,8 +187,8 @@ std::optional<BinaryResponse> AudioToolboxDecoder::Impl::Decode(const BinaryRequ | ||||||
|         return std::nullopt; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // 1024 samples, up to 2 channels each
 |     // Up to 2048 samples, up to 2 channels each
 | ||||||
|     s16 decoder_output[2048]; |     s16 decoder_output[4096]; | ||||||
|     AudioBufferList out_buffer{1, |     AudioBufferList out_buffer{1, | ||||||
|                                {{ |                                {{ | ||||||
|                                    output_format.mChannelsPerFrame, |                                    output_format.mChannelsPerFrame, | ||||||
|  | @ -208,8 +208,8 @@ std::optional<BinaryResponse> AudioToolboxDecoder::Impl::Decode(const BinaryRequ | ||||||
|     // De-interleave samples.
 |     // De-interleave samples.
 | ||||||
|     std::array<std::vector<s16>, 2> out_streams; |     std::array<std::vector<s16>, 2> out_streams; | ||||||
|     auto num_frames = num_packets * output_format.mFramesPerPacket; |     auto num_frames = num_packets * output_format.mFramesPerPacket; | ||||||
|     for (auto frame = 0; frame < num_frames; frame++) { |     for (u32 frame = 0; frame < num_frames; frame++) { | ||||||
|         for (auto ch = 0; ch < output_format.mChannelsPerFrame; ch++) { |         for (u32 ch = 0; ch < output_format.mChannelsPerFrame; ch++) { | ||||||
|             out_streams[ch].push_back( |             out_streams[ch].push_back( | ||||||
|                 decoder_output[(frame * output_format.mChannelsPerFrame) + ch]); |                 decoder_output[(frame * output_format.mChannelsPerFrame) + ch]); | ||||||
|         } |         } | ||||||
|  | @ -223,16 +223,17 @@ std::optional<BinaryResponse> AudioToolboxDecoder::Impl::Decode(const BinaryRequ | ||||||
|     response.num_samples = num_frames; |     response.num_samples = num_frames; | ||||||
| 
 | 
 | ||||||
|     // transfer the decoded buffer from vector to the FCRAM
 |     // transfer the decoded buffer from vector to the FCRAM
 | ||||||
|     for (auto ch = 0; ch < out_streams.size(); ch++) { |     for (std::size_t ch = 0; ch < out_streams.size(); ch++) { | ||||||
|         if (!out_streams[ch].empty()) { |         if (!out_streams[ch].empty()) { | ||||||
|  |             auto byte_size = out_streams[ch].size() * bytes_per_sample; | ||||||
|             auto dst = ch == 0 ? request.dst_addr_ch0 : request.dst_addr_ch1; |             auto dst = ch == 0 ? request.dst_addr_ch0 : request.dst_addr_ch1; | ||||||
|             if (dst < Memory::FCRAM_PADDR || |             if (dst < Memory::FCRAM_PADDR || | ||||||
|                 dst + out_streams[ch].size() > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |                 dst + byte_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|                 LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch{} {:08x}", ch, dst); |                 LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch{} {:08x}", ch, dst); | ||||||
|                 return {}; |                 return {}; | ||||||
|             } |             } | ||||||
|             std::memcpy(memory.GetFCRAMPointer(dst - Memory::FCRAM_PADDR), out_streams[ch].data(), |             std::memcpy(memory.GetFCRAMPointer(dst - Memory::FCRAM_PADDR), out_streams[ch].data(), | ||||||
|                         out_streams[ch].size() * bytes_per_sample); |                         byte_size); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -143,8 +143,8 @@ std::optional<BinaryResponse> FDKDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
| 
 | 
 | ||||||
|     // decoding loops
 |     // decoding loops
 | ||||||
|     AAC_DECODER_ERROR result = AAC_DEC_OK; |     AAC_DECODER_ERROR result = AAC_DEC_OK; | ||||||
|     // 8192 units of s16 are enough to hold one frame of AAC-LC or AAC-HE/v2 data
 |     // Up to 2048 samples, up to 2 channels each
 | ||||||
|     s16 decoder_output[8192]; |     s16 decoder_output[4096]; | ||||||
|     // note that we don't free this pointer as it is automatically freed by fdk_aac
 |     // note that we don't free this pointer as it is automatically freed by fdk_aac
 | ||||||
|     CStreamInfo* stream_info; |     CStreamInfo* stream_info; | ||||||
|     // how many bytes to be queued into the decoder, decrementing from the buffer size
 |     // how many bytes to be queued into the decoder, decrementing from the buffer size
 | ||||||
|  | @ -162,19 +162,21 @@ std::optional<BinaryResponse> FDKDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
|             return std::nullopt; |             return std::nullopt; | ||||||
|         } |         } | ||||||
|         // get output from decoder
 |         // get output from decoder
 | ||||||
|         result = aacDecoder_DecodeFrame(decoder, decoder_output, 8192, 0); |         result = aacDecoder_DecodeFrame(decoder, decoder_output, | ||||||
|  |                                         sizeof(decoder_output) / sizeof(s16), 0); | ||||||
|         if (result == AAC_DEC_OK) { |         if (result == AAC_DEC_OK) { | ||||||
|             // get the stream information
 |             // get the stream information
 | ||||||
|             stream_info = aacDecoder_GetStreamInfo(decoder); |             stream_info = aacDecoder_GetStreamInfo(decoder); | ||||||
|             // fill the stream information for binary response
 |             // fill the stream information for binary response
 | ||||||
|             response.sample_rate = GetSampleRateEnum(stream_info->sampleRate); |             response.sample_rate = GetSampleRateEnum(stream_info->sampleRate); | ||||||
|             response.num_channels = stream_info->aacNumChannels; |             response.num_channels = stream_info->numChannels; | ||||||
|             response.num_samples = stream_info->frameSize; |             response.num_samples = stream_info->frameSize; | ||||||
|             // fill the output
 |             // fill the output
 | ||||||
|             // the sample size = frame_size * channel_counts
 |             // the sample size = frame_size * channel_counts
 | ||||||
|             for (int sample = 0; sample < (stream_info->frameSize * 2); sample++) { |             for (int sample = 0; sample < stream_info->frameSize; sample++) { | ||||||
|                 for (int ch = 0; ch < stream_info->aacNumChannels; ch++) { |                 for (int ch = 0; ch < stream_info->numChannels; ch++) { | ||||||
|                     out_streams[ch].push_back(decoder_output[(sample * 2) + 1]); |                     out_streams[ch].push_back( | ||||||
|  |                         decoder_output[(sample * stream_info->numChannels) + ch]); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } else if (result == AAC_DEC_TRANSPORT_SYNC_ERROR) { |         } else if (result == AAC_DEC_TRANSPORT_SYNC_ERROR) { | ||||||
|  | @ -186,28 +188,22 @@ std::optional<BinaryResponse> FDKDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
|             return std::nullopt; |             return std::nullopt; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     // transfer the decoded buffer from vector to the FCRAM
 |     // transfer the decoded buffer from vector to the FCRAM
 | ||||||
|     if (out_streams[0].size() != 0) { |     for (std::size_t ch = 0; ch < out_streams.size(); ch++) { | ||||||
|         if (request.dst_addr_ch0 < Memory::FCRAM_PADDR || |         if (!out_streams[ch].empty()) { | ||||||
|             request.dst_addr_ch0 + out_streams[0].size() > |             auto byte_size = out_streams[ch].size() * sizeof(s16); | ||||||
|                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |             auto dst = ch == 0 ? request.dst_addr_ch0 : request.dst_addr_ch1; | ||||||
|             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", request.dst_addr_ch0); |             if (dst < Memory::FCRAM_PADDR || | ||||||
|  |                 dst + byte_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  |                 LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch{} {:08x}", ch, dst); | ||||||
|                 return {}; |                 return {}; | ||||||
|             } |             } | ||||||
|         std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch0 - Memory::FCRAM_PADDR), |             std::memcpy(memory.GetFCRAMPointer(dst - Memory::FCRAM_PADDR), out_streams[ch].data(), | ||||||
|                     out_streams[0].data(), out_streams[0].size()); |                         byte_size); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (out_streams[1].size() != 0) { |  | ||||||
|         if (request.dst_addr_ch1 < Memory::FCRAM_PADDR || |  | ||||||
|             request.dst_addr_ch1 + out_streams[1].size() > |  | ||||||
|                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |  | ||||||
|             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", request.dst_addr_ch1); |  | ||||||
|             return {}; |  | ||||||
|         } |  | ||||||
|         std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), |  | ||||||
|                     out_streams[1].data(), out_streams[1].size()); |  | ||||||
|     } |  | ||||||
|     return response; |     return response; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue