1 // Copyright (c) 2012- PPSSPP Project. 2 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, version 2.0 or later versions. 6 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License 2.0 for more details. 11 12 // A copy of the GPL 2.0 should have been included with the program. 13 // If not, see http://www.gnu.org/licenses/ 14 15 // Official git repository and contact information can be found at 16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. 17 18 #include <algorithm> 19 20 #include "Common/Serialize/Serializer.h" 21 #include "Common/Serialize/SerializeFuncs.h" 22 #include "Core/HLE/HLE.h" 23 #include "Core/HLE/FunctionWrappers.h" 24 #include "Core/MIPS/MIPS.h" 25 #include "Core/CoreTiming.h" 26 #include "Core/MemMapHelpers.h" 27 #include "Core/Reporting.h" 28 #include "Core/Config.h" 29 #include "Core/Debugger/MemBlockInfo.h" 30 #include "Core/HW/MediaEngine.h" 31 #include "Core/HW/BufferQueue.h" 32 33 #include "Core/HLE/sceKernel.h" 34 #include "Core/HLE/sceUtility.h" 35 #include "Core/HLE/sceKernelMemory.h" 36 #include "Core/HLE/sceAtrac.h" 37 38 // Notes about sceAtrac buffer management 39 // 40 // sceAtrac decodes from a buffer the game fills, where this buffer is one of: 41 // * Not yet initialized (state NO DATA = 1) 42 // * The entire size of the audio data, and filled with audio data (state ALL DATA LOADED = 2) 43 // * The entire size, but only partially filled so far (state HALFWAY BUFFER = 3) 44 // * Smaller than the audio, sliding without any loop (state STREAMED WITHOUT LOOP = 4) 45 // * Smaller than the audio, sliding with a loop at the end (state STREAMED WITH LOOP AT END = 5) 46 // * Smaller with a second buffer to help with a loop in the middle (state STREAMED WITH SECOND BUF = 6) 47 // * Not managed, decoding using "low level" manual looping etc. (LOW LEVEL = 8) 48 // * Not managed, reserved externally - possibly by sceSas - through low level (RESERVED = 16) 49 // 50 // This buffer is generally filled by sceAtracAddStreamData, and where to fill it is given by 51 // either sceAtracGetStreamDataInfo when continuing to move forwards in the stream of audio data, 52 // or sceAtracGetBufferInfoForResetting when seeking to a specific location in the audio stream. 53 // 54 // State 6 indicates a second buffer is needed. This buffer is used to manage looping correctly. 55 // To determine how to fill it, the game will call sceAtracGetSecondBufferInfo, then after filling 56 // the buffer it will call sceAtracSetSecondBuffer. 57 // The second buffer will just contain the data for the end of loop. The "first" buffer may manage 58 // only the looped portion, or some of the part after the loop (depending on second buf size.) 59 // 60 // Most files will be in RIFF format. It's also possible to load in an OMA/AA3 format file, but 61 // ultimately this will share the same buffer - it's just offset a bit more. 62 // 63 // Low level decoding doesn't use the buffer, and decodes only a single packet at a time. 64 // 65 // Lastly, sceSas has some integration with sceAtrac, which allows setting an Atrac id as 66 // a voice for an SAS core. In this mode, the game will directly modify some of the context, 67 // but will largely only interact using sceSas. 68 // 69 // Note that this buffer is THE view of the audio stream. On a PSP, the firmware does not manage 70 // any cache or separate version of the buffer - at most it manages decode state from earlier in 71 // the buffer. 72 73 #define ATRAC_ERROR_API_FAIL 0x80630002 74 #define ATRAC_ERROR_NO_ATRACID 0x80630003 75 #define ATRAC_ERROR_INVALID_CODECTYPE 0x80630004 76 #define ATRAC_ERROR_BAD_ATRACID 0x80630005 77 #define ATRAC_ERROR_UNKNOWN_FORMAT 0x80630006 78 #define ATRAC_ERROR_WRONG_CODECTYPE 0x80630007 79 #define ATRAC_ERROR_BAD_CODEC_PARAMS 0x80630008 80 #define ATRAC_ERROR_ALL_DATA_LOADED 0x80630009 81 #define ATRAC_ERROR_NO_DATA 0x80630010 82 #define ATRAC_ERROR_SIZE_TOO_SMALL 0x80630011 83 #define ATRAC_ERROR_SECOND_BUFFER_NEEDED 0x80630012 84 #define ATRAC_ERROR_INCORRECT_READ_SIZE 0x80630013 85 #define ATRAC_ERROR_BAD_SAMPLE 0x80630015 86 #define ATRAC_ERROR_BAD_FIRST_RESET_SIZE 0x80630016 87 #define ATRAC_ERROR_BAD_SECOND_RESET_SIZE 0x80630017 88 #define ATRAC_ERROR_ADD_DATA_IS_TOO_BIG 0x80630018 89 #define ATRAC_ERROR_NOT_MONO 0x80630019 90 #define ATRAC_ERROR_NO_LOOP_INFORMATION 0x80630021 91 #define ATRAC_ERROR_SECOND_BUFFER_NOT_NEEDED 0x80630022 92 #define ATRAC_ERROR_BUFFER_IS_EMPTY 0x80630023 93 #define ATRAC_ERROR_ALL_DATA_DECODED 0x80630024 94 #define ATRAC_ERROR_IS_LOW_LEVEL 0x80630031 95 #define ATRAC_ERROR_IS_FOR_SCESAS 0x80630040 96 #define ATRAC_ERROR_AA3_INVALID_DATA 0x80631003 97 #define ATRAC_ERROR_AA3_SIZE_TOO_SMALL 0x80631004 98 99 #define AT3_MAGIC 0x0270 100 #define AT3_PLUS_MAGIC 0xFFFE 101 #define PSP_MODE_AT_3_PLUS 0x00001000 102 #define PSP_MODE_AT_3 0x00001001 103 104 const int RIFF_CHUNK_MAGIC = 0x46464952; 105 const int RIFF_WAVE_MAGIC = 0x45564157; 106 const int FMT_CHUNK_MAGIC = 0x20746D66; 107 const int DATA_CHUNK_MAGIC = 0x61746164; 108 const int SMPL_CHUNK_MAGIC = 0x6C706D73; 109 const int FACT_CHUNK_MAGIC = 0x74636166; 110 111 const int PSP_ATRAC_ALLDATA_IS_ON_MEMORY = -1; 112 const int PSP_ATRAC_NONLOOP_STREAM_DATA_IS_ON_MEMORY = -2; 113 const int PSP_ATRAC_LOOP_STREAM_DATA_IS_ON_MEMORY = -3; 114 115 const u32 ATRAC3_MAX_SAMPLES = 0x400; 116 const u32 ATRAC3PLUS_MAX_SAMPLES = 0x800; 117 118 static const int atracDecodeDelay = 2300; 119 120 #ifdef USE_FFMPEG 121 122 extern "C" { 123 #include "libavformat/avformat.h" 124 #include "libswresample/swresample.h" 125 #include "libavutil/samplefmt.h" 126 } 127 128 #endif // USE_FFMPEG 129 130 enum AtracDecodeResult { 131 ATDECODE_FAILED = -1, 132 ATDECODE_FEEDME = 0, 133 ATDECODE_GOTFRAME = 1, 134 ATDECODE_BADFRAME = 2, 135 }; 136 137 struct InputBuffer { 138 // Address of the buffer. 139 u32 addr; 140 // Size of data read so far into dataBuf_ (to be removed.) 141 u32 size; 142 // Offset into addr at which new data is added. 143 u32 offset; 144 // Last writableBytes number (to be removed.) 145 u32 writableBytes; 146 // Unused, always 0. 147 u32 neededBytes; 148 // Total size of the entire file data. 149 u32 filesize; 150 // Offset into the file at which new data is read. 151 u32 fileoffset; 152 }; 153 154 struct Atrac; 155 int __AtracSetContext(Atrac *atrac); 156 void _AtracGenerateContext(Atrac *atrac); 157 158 struct AtracLoopInfo { 159 int cuePointID; 160 int type; 161 int startSample; 162 int endSample; 163 int fraction; 164 int playCount; 165 }; 166 167 #ifndef USE_FFMPEG 168 struct AVPacket { 169 uint8_t *data; 170 int size; 171 int64_t pos; 172 }; 173 #endif 174 175 struct Atrac { 176 Atrac() : atracID_(-1), dataBuf_(0), decodePos_(0), bufferPos_(0), 177 channels_(0), outputChannels_(2), bitrate_(64), bytesPerFrame_(0), bufferMaxSize_(0), jointStereo_(0), 178 currentSample_(0), endSample_(0), firstSampleOffset_(0), dataOff_(0), 179 loopStartSample_(-1), loopEndSample_(-1), loopNum_(0), 180 failedDecode_(false), ignoreDataBuf_(false), codecType_(0), 181 bufferState_(ATRAC_STATUS_NO_DATA) { 182 memset(&first_, 0, sizeof(first_)); 183 memset(&second_, 0, sizeof(second_)); 184 #ifdef USE_FFMPEG 185 codecCtx_ = nullptr; 186 swrCtx_ = nullptr; 187 frame_ = nullptr; 188 packet_ = nullptr; 189 #endif // USE_FFMPEG 190 context_ = 0; 191 } 192 193 ~Atrac() { 194 ResetData(); 195 } 196 197 void ResetData() { 198 #ifdef USE_FFMPEG 199 ReleaseFFMPEGContext(); 200 #endif // USE_FFMPEG 201 202 if (dataBuf_) 203 delete [] dataBuf_; 204 dataBuf_ = 0; 205 ignoreDataBuf_ = false; 206 bufferState_ = ATRAC_STATUS_NO_DATA; 207 208 if (context_.IsValid()) 209 kernelMemory.Free(context_.ptr); 210 211 // Clean slate time. 212 failedDecode_ = false; 213 } 214 215 void SetBufferState() { 216 if (bufferMaxSize_ >= first_.filesize) { 217 if (first_.size < first_.filesize) { 218 // The buffer is big enough, but we don't have all the data yet. 219 bufferState_ = ATRAC_STATUS_HALFWAY_BUFFER; 220 } else { 221 bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED; 222 } 223 } else { 224 if (loopEndSample_ <= 0) { 225 // There's no looping, but we need to stream the data in our buffer. 226 bufferState_ = ATRAC_STATUS_STREAMED_WITHOUT_LOOP; 227 } else if (loopEndSample_ == endSample_ + firstSampleOffset_ + (int)FirstOffsetExtra()) { 228 bufferState_ = ATRAC_STATUS_STREAMED_LOOP_FROM_END; 229 } else { 230 bufferState_ = ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER; 231 } 232 } 233 } 234 235 void DoState(PointerWrap &p) { 236 auto s = p.Section("Atrac", 1, 9); 237 if (!s) 238 return; 239 240 Do(p, channels_); 241 Do(p, outputChannels_); 242 if (s >= 5) { 243 Do(p, jointStereo_); 244 } 245 246 Do(p, atracID_); 247 Do(p, first_); 248 Do(p, bufferMaxSize_); 249 Do(p, codecType_); 250 251 Do(p, currentSample_); 252 Do(p, endSample_); 253 Do(p, firstSampleOffset_); 254 if (s >= 3) { 255 Do(p, dataOff_); 256 } else { 257 dataOff_ = firstSampleOffset_; 258 } 259 260 u32 hasDataBuf = dataBuf_ != nullptr; 261 Do(p, hasDataBuf); 262 if (hasDataBuf) { 263 if (p.mode == p.MODE_READ) { 264 if (dataBuf_) 265 delete [] dataBuf_; 266 dataBuf_ = new u8[first_.filesize]; 267 } 268 DoArray(p, dataBuf_, first_.filesize); 269 } 270 Do(p, second_); 271 272 Do(p, decodePos_); 273 if (s < 9) { 274 u32 oldDecodeEnd = 0; 275 Do(p, oldDecodeEnd); 276 } 277 if (s >= 4) { 278 Do(p, bufferPos_); 279 } else { 280 bufferPos_ = decodePos_; 281 } 282 283 Do(p, bitrate_); 284 Do(p, bytesPerFrame_); 285 286 Do(p, loopinfo_); 287 if (s < 9) { 288 int oldLoopInfoNum = 42; 289 Do(p, oldLoopInfoNum); 290 } 291 292 Do(p, loopStartSample_); 293 Do(p, loopEndSample_); 294 Do(p, loopNum_); 295 296 Do(p, context_); 297 if (s >= 6) { 298 Do(p, bufferState_); 299 } else { 300 if (dataBuf_ == nullptr) { 301 bufferState_ = ATRAC_STATUS_NO_DATA; 302 } else { 303 SetBufferState(); 304 } 305 } 306 307 if (s >= 7) { 308 Do(p, ignoreDataBuf_); 309 } else { 310 ignoreDataBuf_ = false; 311 } 312 313 if (s >= 9) { 314 Do(p, bufferValidBytes_); 315 Do(p, bufferHeaderSize_); 316 } else { 317 bufferHeaderSize_ = dataOff_; 318 bufferValidBytes_ = std::min(first_.size - dataOff_, StreamBufferEnd() - dataOff_); 319 if ((bufferState_ & ATRAC_STATUS_STREAMED_MASK) == ATRAC_STATUS_STREAMED_MASK) { 320 bufferPos_ = dataOff_; 321 } 322 } 323 324 if (s < 8 && bufferState_ == ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER) { 325 // We didn't actually allow the second buffer to be set this far back. 326 // Pretend it's a regular loop, we'll just try our best. 327 bufferState_ = ATRAC_STATUS_STREAMED_LOOP_FROM_END; 328 } 329 330 // Make sure to do this late; it depends on things like bytesPerFrame_. 331 if (p.mode == p.MODE_READ && bufferState_ != ATRAC_STATUS_NO_DATA) { 332 __AtracSetContext(this); 333 } 334 335 if (s >= 2 && s < 9) { 336 bool oldResetBuffer = false; 337 Do(p, oldResetBuffer); 338 } 339 } 340 341 int Analyze(u32 addr, u32 size); 342 int AnalyzeAA3(u32 addr, u32 size, u32 filesize); 343 344 u32 SamplesPerFrame() const { 345 return codecType_ == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES; 346 } 347 348 u32 FirstOffsetExtra() const { 349 return codecType_ == PSP_CODEC_AT3PLUS ? 368 : 69; 350 } 351 352 u32 DecodePosBySample(int sample) const { 353 return (u32)(firstSampleOffset_ + sample / (int)SamplesPerFrame() * bytesPerFrame_); 354 } 355 356 u32 FileOffsetBySample(int sample) const { 357 int offsetSample = sample + firstSampleOffset_; 358 int frameOffset = offsetSample / (int)SamplesPerFrame(); 359 return (u32)(dataOff_ + bytesPerFrame_ + frameOffset * bytesPerFrame_); 360 } 361 362 int RemainingFrames() const { 363 if (bufferState_ == ATRAC_STATUS_ALL_DATA_LOADED) { 364 // Meaning, infinite I guess? We've got it all. 365 return PSP_ATRAC_ALLDATA_IS_ON_MEMORY; 366 } 367 368 u32 currentFileOffset = FileOffsetBySample(currentSample_ - SamplesPerFrame() + FirstOffsetExtra()); 369 if (first_.fileoffset >= first_.filesize) { 370 if (bufferState_ == ATRAC_STATUS_STREAMED_WITHOUT_LOOP) { 371 return PSP_ATRAC_NONLOOP_STREAM_DATA_IS_ON_MEMORY; 372 } 373 int loopEndAdjusted = loopEndSample_ - FirstOffsetExtra() - firstSampleOffset_; 374 if (bufferState_ == ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER && currentSample_ > loopEndAdjusted) { 375 // No longer looping in this case, outside the loop. 376 return PSP_ATRAC_NONLOOP_STREAM_DATA_IS_ON_MEMORY; 377 } 378 if ((bufferState_ & ATRAC_STATUS_STREAMED_MASK) == ATRAC_STATUS_STREAMED_MASK && loopNum_ == 0) { 379 return PSP_ATRAC_LOOP_STREAM_DATA_IS_ON_MEMORY; 380 } 381 } 382 383 if ((bufferState_ & ATRAC_STATUS_STREAMED_MASK) == ATRAC_STATUS_STREAMED_MASK) { 384 // Since we're streaming, the remaining frames are what's valid in the buffer. 385 return bufferValidBytes_ / bytesPerFrame_; 386 } 387 388 // Since the first frame is shorter by this offset, add to round up at this offset. 389 const int remainingBytes = first_.fileoffset - currentFileOffset; 390 if (remainingBytes < 0) { 391 // Just in case. Shouldn't happen, but once did by mistake. 392 return 0; 393 } 394 return remainingBytes / bytesPerFrame_; 395 } 396 397 int atracID_; 398 u8 *dataBuf_; 399 400 u32 decodePos_; 401 // Used by low-level decoding and to track streaming. 402 u32 bufferPos_; 403 u32 bufferValidBytes_; 404 u32 bufferHeaderSize_; 405 406 u16 channels_; 407 u16 outputChannels_; 408 u32 bitrate_; 409 u16 bytesPerFrame_; 410 u32 bufferMaxSize_; 411 int jointStereo_; 412 413 int currentSample_; 414 int endSample_; 415 int firstSampleOffset_; 416 // Offset of the first sample in the input buffer 417 int dataOff_; 418 419 std::vector<AtracLoopInfo> loopinfo_; 420 421 int loopStartSample_; 422 int loopEndSample_; 423 int loopNum_; 424 425 bool failedDecode_; 426 // Indicates that the dataBuf_ array should not be used. 427 bool ignoreDataBuf_; 428 429 u32 codecType_; 430 AtracStatus bufferState_; 431 432 InputBuffer first_; 433 InputBuffer second_; 434 435 PSPPointer<SceAtracId> context_; 436 437 #ifdef USE_FFMPEG 438 AVCodecContext *codecCtx_ = nullptr; 439 SwrContext *swrCtx_ = nullptr; 440 AVFrame *frame_ = nullptr; 441 AVPacket *packet_ = nullptr; 442 #endif // USE_FFMPEG 443 444 #ifdef USE_FFMPEG 445 void ReleaseFFMPEGContext() { 446 // All of these allow null pointers. 447 av_freep(&frame_); 448 swr_free(&swrCtx_); 449 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 52, 0) 450 // If necessary, extradata is automatically freed. 451 avcodec_free_context(&codecCtx_); 452 #else 453 // Future versions may add other things to free, but avcodec_free_context didn't exist yet here. 454 // Some old versions crash when we try to free extradata and subtitle_header, so let's not. A minor 455 // leak is better than a segfualt. 456 // av_freep(&codecCtx_->extradata); 457 // av_freep(&codecCtx_->subtitle_header); 458 avcodec_close(codecCtx_); 459 av_freep(&codecCtx_); 460 #endif 461 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 462 av_packet_free(&packet_); 463 #else 464 av_free_packet(packet_); 465 delete packet_; 466 packet_ = nullptr; 467 #endif 468 } 469 #endif // USE_FFMPEG 470 471 void ForceSeekToSample(int sample) { 472 #ifdef USE_FFMPEG 473 avcodec_flush_buffers(codecCtx_); 474 475 // Discard any pending packet data. 476 packet_->size = 0; 477 #endif 478 479 currentSample_ = sample; 480 } 481 482 u8 *BufferStart() { 483 return ignoreDataBuf_ ? Memory::GetPointer(first_.addr) : dataBuf_; 484 } 485 486 void SeekToSample(int sample) { 487 #ifdef USE_FFMPEG 488 // Discard any pending packet data. 489 packet_->size = 0; 490 491 // It seems like the PSP aligns the sample position to 0x800...? 492 const u32 offsetSamples = firstSampleOffset_ + FirstOffsetExtra(); 493 const u32 unalignedSamples = (offsetSamples + sample) % SamplesPerFrame(); 494 int seekFrame = sample + offsetSamples - unalignedSamples; 495 496 if ((sample != currentSample_ || sample == 0) && codecCtx_ != nullptr) { 497 // Prefill the decode buffer with packets before the first sample offset. 498 avcodec_flush_buffers(codecCtx_); 499 500 int adjust = 0; 501 if (sample == 0) { 502 int offsetSamples = firstSampleOffset_ + FirstOffsetExtra(); 503 adjust = -(int)(offsetSamples % SamplesPerFrame()); 504 } 505 const u32 off = FileOffsetBySample(sample + adjust); 506 const u32 backfill = bytesPerFrame_ * 2; 507 const u32 start = off - dataOff_ < backfill ? dataOff_ : off - backfill; 508 for (u32 pos = start; pos < off; pos += bytesPerFrame_) { 509 av_init_packet(packet_); 510 packet_->data = BufferStart() + pos; 511 packet_->size = bytesPerFrame_; 512 packet_->pos = pos; 513 514 // Process the packet, we don't care about success. 515 DecodePacket(); 516 } 517 } 518 #endif // USE_FFMPEG 519 520 currentSample_ = sample; 521 } 522 523 uint32_t CurBufferAddress(int adjust = 0) { 524 u32 off = FileOffsetBySample(currentSample_ + adjust); 525 if (off < first_.size && ignoreDataBuf_) { 526 return first_.addr + off; 527 } 528 // If it's in dataBug, it's not in PSP memory. 529 return 0; 530 } 531 532 bool FillPacket(int adjust = 0) { 533 u32 off = FileOffsetBySample(currentSample_ + adjust); 534 if (off < first_.size) { 535 #ifdef USE_FFMPEG 536 av_init_packet(packet_); 537 packet_->data = BufferStart() + off; 538 packet_->size = std::min((u32)bytesPerFrame_, first_.size - off); 539 packet_->pos = off; 540 #endif // USE_FFMPEG 541 542 return true; 543 } else { 544 return false; 545 } 546 547 return true; 548 } 549 550 bool FillLowLevelPacket(u8 *ptr) { 551 #ifdef USE_FFMPEG 552 av_init_packet(packet_); 553 554 packet_->data = ptr; 555 packet_->size = bytesPerFrame_; 556 packet_->pos = 0; 557 #endif // USE_FFMPEG 558 return true; 559 } 560 561 AtracDecodeResult DecodePacket() { 562 #ifdef USE_FFMPEG 563 if (codecCtx_ == nullptr) { 564 return ATDECODE_FAILED; 565 } 566 567 int got_frame = 0; 568 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101) 569 if (packet_->size != 0) { 570 int err = avcodec_send_packet(codecCtx_, packet_); 571 if (err < 0) { 572 ERROR_LOG_REPORT(ME, "avcodec_send_packet: Error decoding audio %d / %08x", err, err); 573 failedDecode_ = true; 574 return ATDECODE_FAILED; 575 } 576 } 577 578 int err = avcodec_receive_frame(codecCtx_, frame_); 579 int bytes_read = 0; 580 if (err >= 0) { 581 bytes_read = frame_->pkt_size; 582 got_frame = 1; 583 } else if (err != AVERROR(EAGAIN)) { 584 bytes_read = err; 585 } 586 #else 587 int bytes_read = avcodec_decode_audio4(codecCtx_, frame_, &got_frame, packet_); 588 #endif 589 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 590 av_packet_unref(packet_); 591 #else 592 av_free_packet(packet_); 593 #endif 594 if (bytes_read == AVERROR_PATCHWELCOME) { 595 ERROR_LOG(ME, "Unsupported feature in ATRAC audio."); 596 // Let's try the next packet. 597 packet_->size = 0; 598 return ATDECODE_BADFRAME; 599 } else if (bytes_read < 0) { 600 ERROR_LOG_REPORT(ME, "avcodec_decode_audio4: Error decoding audio %d / %08x", bytes_read, bytes_read); 601 failedDecode_ = true; 602 return ATDECODE_FAILED; 603 } 604 605 return got_frame ? ATDECODE_GOTFRAME : ATDECODE_FEEDME; 606 #else 607 return ATDECODE_BADFRAME; 608 #endif // USE_FFMPEG 609 } 610 611 void CalculateStreamInfo(u32 *readOffset); 612 613 u32 StreamBufferEnd() const { 614 // The buffer is always aligned to a frame in size, not counting an optional header. 615 // The header will only initially exist after the data is first set. 616 u32 framesAfterHeader = (bufferMaxSize_ - bufferHeaderSize_) / bytesPerFrame_; 617 return framesAfterHeader * bytesPerFrame_ + bufferHeaderSize_; 618 } 619 620 void ConsumeFrame() { 621 bufferPos_ += bytesPerFrame_; 622 if (bufferValidBytes_ > bytesPerFrame_) { 623 bufferValidBytes_ -= bytesPerFrame_; 624 } else { 625 bufferValidBytes_ = 0; 626 } 627 if (bufferPos_ >= StreamBufferEnd()) { 628 // Wrap around... theoretically, this should only happen at exactly StreamBufferEnd. 629 bufferPos_ -= StreamBufferEnd(); 630 bufferHeaderSize_ = 0; 631 } 632 } 633 634 private: 635 void AnalyzeReset(); 636 }; 637 638 struct AtracSingleResetBufferInfo { 639 u32_le writePosPtr; 640 u32_le writableBytes; 641 u32_le minWriteBytes; 642 u32_le filePos; 643 }; 644 645 struct AtracResetBufferInfo { 646 AtracSingleResetBufferInfo first; 647 AtracSingleResetBufferInfo second; 648 }; 649 650 const int PSP_NUM_ATRAC_IDS = 6; 651 static bool atracInited = true; 652 static Atrac *atracIDs[PSP_NUM_ATRAC_IDS]; 653 static u32 atracIDTypes[PSP_NUM_ATRAC_IDS]; 654 655 void __AtracInit() { 656 atracInited = true; 657 memset(atracIDs, 0, sizeof(atracIDs)); 658 659 // Start with 2 of each in this order. 660 atracIDTypes[0] = PSP_MODE_AT_3_PLUS; 661 atracIDTypes[1] = PSP_MODE_AT_3_PLUS; 662 atracIDTypes[2] = PSP_MODE_AT_3; 663 atracIDTypes[3] = PSP_MODE_AT_3; 664 atracIDTypes[4] = 0; 665 atracIDTypes[5] = 0; 666 667 #ifdef USE_FFMPEG 668 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 18, 100) 669 avcodec_register_all(); 670 #endif 671 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 12, 100) 672 av_register_all(); 673 #endif 674 #endif // USE_FFMPEG 675 } 676 677 void __AtracDoState(PointerWrap &p) { 678 auto s = p.Section("sceAtrac", 1); 679 if (!s) 680 return; 681 682 Do(p, atracInited); 683 for (int i = 0; i < PSP_NUM_ATRAC_IDS; ++i) { 684 bool valid = atracIDs[i] != NULL; 685 Do(p, valid); 686 if (valid) { 687 Do(p, atracIDs[i]); 688 } else { 689 delete atracIDs[i]; 690 atracIDs[i] = NULL; 691 } 692 } 693 DoArray(p, atracIDTypes, PSP_NUM_ATRAC_IDS); 694 } 695 696 void __AtracShutdown() { 697 for (size_t i = 0; i < ARRAY_SIZE(atracIDs); ++i) { 698 delete atracIDs[i]; 699 atracIDs[i] = NULL; 700 } 701 } 702 703 static Atrac *getAtrac(int atracID) { 704 if (atracID < 0 || atracID >= PSP_NUM_ATRAC_IDS) { 705 return NULL; 706 } 707 Atrac *atrac = atracIDs[atracID]; 708 709 if (atrac && atrac->context_.IsValid()) { 710 // Read in any changes from the game to the context. 711 // TODO: Might be better to just always track in RAM. 712 atrac->bufferState_ = atrac->context_->info.state; 713 // This value is actually abused by games to store the SAS voice number. 714 atrac->loopNum_ = atrac->context_->info.loopNum; 715 } 716 717 return atrac; 718 } 719 720 static int createAtrac(Atrac *atrac) { 721 for (int i = 0; i < (int)ARRAY_SIZE(atracIDs); ++i) { 722 if (atracIDTypes[i] == atrac->codecType_ && atracIDs[i] == 0) { 723 atracIDs[i] = atrac; 724 atrac->atracID_ = i; 725 return i; 726 } 727 } 728 729 return ATRAC_ERROR_NO_ATRACID; 730 } 731 732 static int deleteAtrac(int atracID) { 733 if (atracID >= 0 && atracID < PSP_NUM_ATRAC_IDS) { 734 if (atracIDs[atracID] != nullptr) { 735 delete atracIDs[atracID]; 736 atracIDs[atracID] = nullptr; 737 738 return 0; 739 } 740 } 741 742 return ATRAC_ERROR_BAD_ATRACID; 743 } 744 745 void Atrac::AnalyzeReset() { 746 // Reset some values. 747 codecType_ = 0; 748 currentSample_ = 0; 749 endSample_ = -1; 750 loopNum_ = 0; 751 loopinfo_.clear(); 752 loopStartSample_ = -1; 753 loopEndSample_ = -1; 754 decodePos_ = 0; 755 bufferPos_ = 0; 756 channels_ = 2; 757 } 758 759 struct RIFFFmtChunk { 760 u16_le fmtTag; 761 u16_le channels; 762 u32_le samplerate; 763 u32_le avgBytesPerSec; 764 u16_le blockAlign; 765 }; 766 767 int Atrac::Analyze(u32 addr, u32 size) { 768 first_.addr = addr; 769 first_.size = size; 770 771 AnalyzeReset(); 772 773 // 72 is about the size of the minimum required data to even be valid. 774 if (first_.size < 72) { 775 return hleReportError(ME, ATRAC_ERROR_SIZE_TOO_SMALL, "buffer too small"); 776 } 777 778 if (!Memory::IsValidAddress(first_.addr)) { 779 return hleReportWarning(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "invalid buffer address"); 780 } 781 782 // TODO: Validate stuff. 783 784 if (Memory::Read_U32(first_.addr) != RIFF_CHUNK_MAGIC) { 785 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "invalid RIFF header"); 786 } 787 788 u32 offset = 8; 789 firstSampleOffset_ = 0; 790 791 while (Memory::Read_U32(first_.addr + offset) != RIFF_WAVE_MAGIC) { 792 // Get the size preceding the magic. 793 int chunk = Memory::Read_U32(first_.addr + offset - 4); 794 // Round the chunk size up to the nearest 2. 795 offset += chunk + (chunk & 1); 796 if (offset + 12 > first_.size) { 797 return hleReportError(ME, ATRAC_ERROR_SIZE_TOO_SMALL, "too small for WAVE chunk at %d", offset); 798 } 799 if (Memory::Read_U32(first_.addr + offset) != RIFF_CHUNK_MAGIC) { 800 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "RIFF chunk did not contain WAVE"); 801 } 802 offset += 8; 803 } 804 offset += 4; 805 806 if (offset != 12) { 807 WARN_LOG_REPORT(ME, "RIFF chunk at offset: %d", offset); 808 } 809 810 // RIFF size excluding chunk header. 811 first_.filesize = Memory::Read_U32(first_.addr + offset - 8) + 8; 812 // Even if the RIFF size is too low, it may simply be incorrect. This works on real firmware. 813 u32 maxSize = std::max(first_.filesize, first_.size); 814 815 bool bfoundData = false; 816 u32 dataChunkSize = 0; 817 int sampleOffsetAdjust = 0; 818 while (maxSize >= offset + 8 && !bfoundData) { 819 int chunkMagic = Memory::Read_U32(first_.addr + offset); 820 u32 chunkSize = Memory::Read_U32(first_.addr + offset + 4); 821 // Account for odd sized chunks. 822 if (chunkSize & 1) { 823 WARN_LOG_REPORT_ONCE(oddchunk, ME, "RIFF chunk had uneven size"); 824 } 825 chunkSize += (chunkSize & 1); 826 offset += 8; 827 if (chunkSize > maxSize - offset) 828 break; 829 switch (chunkMagic) { 830 case FMT_CHUNK_MAGIC: 831 { 832 if (codecType_ != 0) { 833 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "multiple fmt definitions"); 834 } 835 836 auto at3fmt = PSPPointer<const RIFFFmtChunk>::Create(first_.addr + offset); 837 if (chunkSize < 32 || (at3fmt->fmtTag == AT3_PLUS_MAGIC && chunkSize < 52)) { 838 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "fmt definition too small (%d)", chunkSize); 839 } 840 841 if (at3fmt->fmtTag == AT3_MAGIC) 842 codecType_ = PSP_MODE_AT_3; 843 else if (at3fmt->fmtTag == AT3_PLUS_MAGIC) 844 codecType_ = PSP_MODE_AT_3_PLUS; 845 else { 846 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "invalid fmt magic: %04x", at3fmt->fmtTag); 847 } 848 channels_ = at3fmt->channels; 849 if (channels_ != 1 && channels_ != 2) { 850 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "invalid channel count: %d", channels_); 851 } 852 if (at3fmt->samplerate != 44100) { 853 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "unsupported sample rate: %d", at3fmt->samplerate); 854 } 855 bitrate_ = at3fmt->avgBytesPerSec * 8; 856 bytesPerFrame_ = at3fmt->blockAlign; 857 if (bytesPerFrame_ == 0) { 858 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "invalid bytes per frame: %d", bytesPerFrame_); 859 } 860 861 // TODO: There are some format specific bytes here which seem to have fixed values? 862 // Probably don't need them. 863 864 if (at3fmt->fmtTag == AT3_MAGIC) { 865 // This is the offset to the jointStereo_ field. 866 jointStereo_ = Memory::Read_U32(first_.addr + offset + 24); 867 } 868 } 869 break; 870 case FACT_CHUNK_MAGIC: 871 { 872 endSample_ = Memory::Read_U32(first_.addr + offset); 873 if (chunkSize >= 8) { 874 firstSampleOffset_ = Memory::Read_U32(first_.addr + offset + 4); 875 } 876 if (chunkSize >= 12) { 877 u32 largerOffset = Memory::Read_U32(first_.addr + offset + 8); 878 sampleOffsetAdjust = firstSampleOffset_ - largerOffset; 879 } 880 } 881 break; 882 case SMPL_CHUNK_MAGIC: 883 { 884 if (chunkSize < 32) { 885 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "smpl chunk too small (%d)", chunkSize); 886 } 887 int checkNumLoops = Memory::Read_U32(first_.addr + offset + 28); 888 if (checkNumLoops != 0 && chunkSize < 36 + 20) { 889 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "smpl chunk too small for loop (%d)", chunkSize); 890 } 891 892 loopinfo_.resize(checkNumLoops); 893 u32 loopinfoAddr = first_.addr + offset + 36; 894 // The PSP only cares about the first loop start and end, it seems. 895 // Most likely can skip the rest of this data, but it's not hurting anyone. 896 for (int i = 0; i < checkNumLoops && 36 + (u32)i < chunkSize; i++, loopinfoAddr += 24) { 897 loopinfo_[i].cuePointID = Memory::Read_U32(loopinfoAddr); 898 loopinfo_[i].type = Memory::Read_U32(loopinfoAddr + 4); 899 loopinfo_[i].startSample = Memory::Read_U32(loopinfoAddr + 8); 900 loopinfo_[i].endSample = Memory::Read_U32(loopinfoAddr + 12); 901 loopinfo_[i].fraction = Memory::Read_U32(loopinfoAddr + 16); 902 loopinfo_[i].playCount = Memory::Read_U32(loopinfoAddr + 20); 903 904 if (loopinfo_[i].startSample >= loopinfo_[i].endSample) { 905 return hleReportError(ME, ATRAC_ERROR_BAD_CODEC_PARAMS, "loop starts after it ends"); 906 } 907 } 908 } 909 break; 910 case DATA_CHUNK_MAGIC: 911 { 912 bfoundData = true; 913 dataOff_ = offset; 914 dataChunkSize = chunkSize; 915 if (first_.filesize < offset + chunkSize) { 916 WARN_LOG_REPORT(ME, "Atrac data chunk extends beyond riff chunk"); 917 first_.filesize = offset + chunkSize; 918 } 919 } 920 break; 921 } 922 offset += chunkSize; 923 } 924 925 if (codecType_ == 0) { 926 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "could not detect codec"); 927 } 928 929 if (!bfoundData) { 930 return hleReportError(ME, ATRAC_ERROR_SIZE_TOO_SMALL, "no data chunk"); 931 } 932 933 // set the loopStartSample_ and loopEndSample_ by loopinfo_ 934 if (loopinfo_.size() > 0) { 935 loopStartSample_ = loopinfo_[0].startSample + FirstOffsetExtra() + sampleOffsetAdjust; 936 loopEndSample_ = loopinfo_[0].endSample + FirstOffsetExtra() + sampleOffsetAdjust; 937 } else { 938 loopStartSample_ = -1; 939 loopEndSample_ = -1; 940 } 941 942 // if there is no correct endsample, try to guess it 943 if (endSample_ <= 0 && bytesPerFrame_ != 0) { 944 endSample_ = (dataChunkSize / bytesPerFrame_) * SamplesPerFrame(); 945 endSample_ -= firstSampleOffset_ + FirstOffsetExtra(); 946 } 947 endSample_ -= 1; 948 949 if (loopEndSample_ != -1 && loopEndSample_ > endSample_ + firstSampleOffset_ + (int)FirstOffsetExtra()) { 950 return hleReportError(ME, ATRAC_ERROR_BAD_CODEC_PARAMS, "loop after end of data"); 951 } 952 953 return 0; 954 } 955 956 int Atrac::AnalyzeAA3(u32 addr, u32 size, u32 filesize) { 957 first_.addr = addr; 958 first_.size = size; 959 first_.filesize = filesize; 960 961 AnalyzeReset(); 962 963 if (first_.size < 10) { 964 return hleReportError(ME, ATRAC_ERROR_AA3_SIZE_TOO_SMALL, "buffer too small"); 965 } 966 967 // TODO: Make sure this validation is correct, more testing. 968 969 const u8 *buffer = Memory::GetPointer(first_.addr); 970 if (buffer[0] != 'e' || buffer[1] != 'a' || buffer[2] != '3') { 971 return hleReportError(ME, ATRAC_ERROR_AA3_INVALID_DATA, "invalid ea3 magic bytes"); 972 } 973 974 // It starts with an id3 header (replaced with ea3.) This is the size. 975 u32 tagSize = buffer[9] | (buffer[8] << 7) | (buffer[7] << 14) | (buffer[6] << 21); 976 if (first_.size < tagSize + 36) { 977 return hleReportError(ME, ATRAC_ERROR_AA3_SIZE_TOO_SMALL, "truncated before id3 end"); 978 } 979 980 // EA3 header starts at id3 header (10) + tagSize. 981 buffer = Memory::GetPointer(first_.addr + 10 + tagSize); 982 if (buffer[0] != 'E' || buffer[1] != 'A' || buffer[2] != '3') { 983 return hleReportError(ME, ATRAC_ERROR_AA3_INVALID_DATA, "invalid EA3 magic bytes"); 984 } 985 986 // Based on FFmpeg's code. 987 u32 codecParams = buffer[35] | (buffer[34] << 8) | (buffer[35] << 16); 988 const u32 at3SampleRates[8] = { 32000, 44100, 48000, 88200, 96000, 0 }; 989 990 switch (buffer[32]) { 991 case 0: 992 codecType_ = PSP_MODE_AT_3; 993 bytesPerFrame_ = (codecParams & 0x03FF) * 8; 994 bitrate_ = at3SampleRates[(codecParams >> 13) & 7] * bytesPerFrame_ * 8 / 1024; 995 channels_ = 2; 996 jointStereo_ = (codecParams >> 17) & 1; 997 break; 998 case 1: 999 codecType_ = PSP_MODE_AT_3_PLUS; 1000 bytesPerFrame_ = ((codecParams & 0x03FF) * 8) + 8; 1001 bitrate_ = at3SampleRates[(codecParams >> 13) & 7] * bytesPerFrame_ * 8 / 2048; 1002 channels_ = (codecParams >> 10) & 7; 1003 break; 1004 case 3: 1005 case 4: 1006 case 5: 1007 return hleReportError(ME, ATRAC_ERROR_AA3_INVALID_DATA, "unsupported codec type %d", buffer[32]); 1008 default: 1009 return hleReportError(ME, ATRAC_ERROR_AA3_INVALID_DATA, "invalid codec type %d", buffer[32]); 1010 } 1011 1012 dataOff_ = 10 + tagSize + 96; 1013 firstSampleOffset_ = 0; 1014 if (endSample_ < 0 && bytesPerFrame_ != 0) { 1015 endSample_ = ((first_.filesize - dataOff_) / bytesPerFrame_) * SamplesPerFrame(); 1016 } 1017 endSample_ -= 1; 1018 1019 return 0; 1020 } 1021 1022 static u32 sceAtracGetAtracID(int codecType) { 1023 if (codecType != PSP_MODE_AT_3 && codecType != PSP_MODE_AT_3_PLUS) { 1024 return hleReportError(ME, ATRAC_ERROR_INVALID_CODECTYPE, "invalid codecType"); 1025 } 1026 1027 Atrac *atrac = new Atrac(); 1028 atrac->codecType_ = codecType; 1029 int atracID = createAtrac(atrac); 1030 if (atracID < 0) { 1031 delete atrac; 1032 return hleLogError(ME, atracID, "no free ID"); 1033 } 1034 1035 return hleLogSuccessInfoI(ME, atracID); 1036 } 1037 1038 u32 _AtracAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd) { 1039 Atrac *atrac = getAtrac(atracID); 1040 if (!atrac) 1041 return 0; 1042 int addbytes = std::min(bytesToAdd, atrac->first_.filesize - atrac->first_.fileoffset); 1043 Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, bufPtr, addbytes, "AtracAddStreamData"); 1044 atrac->first_.size += bytesToAdd; 1045 if (atrac->first_.size >= atrac->first_.filesize) { 1046 atrac->first_.size = atrac->first_.filesize; 1047 if (atrac->bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER) 1048 atrac->bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED; 1049 } 1050 atrac->first_.fileoffset += addbytes; 1051 if (atrac->context_.IsValid()) { 1052 // refresh context_ 1053 _AtracGenerateContext(atrac); 1054 } 1055 return 0; 1056 } 1057 1058 static u32 AtracValidateManaged(const Atrac *atrac) { 1059 if (!atrac) { 1060 return hleLogError(ME, ATRAC_ERROR_BAD_ATRACID, "bad atrac ID"); 1061 } else if (atrac->bufferState_ == ATRAC_STATUS_NO_DATA) { 1062 return hleLogError(ME, ATRAC_ERROR_NO_DATA, "no data"); 1063 } else if (atrac->bufferState_ == ATRAC_STATUS_LOW_LEVEL) { 1064 return hleLogError(ME, ATRAC_ERROR_IS_LOW_LEVEL, "cannot use for low level stream"); 1065 } else if (atrac->bufferState_ == ATRAC_STATUS_FOR_SCESAS) { 1066 return hleLogError(ME, ATRAC_ERROR_IS_FOR_SCESAS, "cannot use for SAS stream"); 1067 } else { 1068 return 0; 1069 } 1070 } 1071 1072 void Atrac::CalculateStreamInfo(u32 *outReadOffset) { 1073 u32 readOffset = first_.fileoffset; 1074 if (bufferState_ == ATRAC_STATUS_ALL_DATA_LOADED) { 1075 // Nothing to write. 1076 readOffset = 0; 1077 first_.offset = 0; 1078 first_.writableBytes = 0; 1079 } else if (bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER) { 1080 // If we're buffering the entire file, just give the same as readOffset. 1081 first_.offset = readOffset; 1082 // In this case, the bytes writable are just the remaining bytes, always. 1083 first_.writableBytes = first_.filesize - readOffset; 1084 } else { 1085 u32 bufferEnd = StreamBufferEnd(); 1086 u32 bufferValidExtended = bufferPos_ + bufferValidBytes_; 1087 if (bufferValidExtended < bufferEnd) { 1088 first_.offset = bufferValidExtended; 1089 first_.writableBytes = bufferEnd - bufferValidExtended; 1090 } else { 1091 u32 bufferStartUsed = bufferValidExtended - bufferEnd; 1092 first_.offset = bufferStartUsed; 1093 first_.writableBytes = bufferPos_ - bufferStartUsed; 1094 } 1095 1096 if (readOffset >= first_.filesize) { 1097 if (bufferState_ == ATRAC_STATUS_STREAMED_WITHOUT_LOOP) { 1098 // We don't need anything more, so all 0s. 1099 readOffset = 0; 1100 first_.offset = 0; 1101 first_.writableBytes = 0; 1102 } else { 1103 readOffset = FileOffsetBySample(loopStartSample_ - FirstOffsetExtra() - firstSampleOffset_ - SamplesPerFrame() * 2); 1104 } 1105 } 1106 1107 if (readOffset + first_.writableBytes > first_.filesize) { 1108 // Never ask for past the end of file, even when the space is free. 1109 first_.writableBytes = first_.filesize - readOffset; 1110 } 1111 1112 // If you don't think this should be here, remove it. It's just a temporary safety check. 1113 if (first_.offset + first_.writableBytes > bufferMaxSize_) { 1114 ERROR_LOG_REPORT(ME, "Somehow calculated too many writable bytes: %d + %d > %d", first_.offset, first_.writableBytes, bufferMaxSize_); 1115 first_.offset = 0; 1116 first_.writableBytes = bufferMaxSize_; 1117 } 1118 } 1119 1120 if (outReadOffset) { 1121 *outReadOffset = readOffset; 1122 } 1123 } 1124 1125 // Notifies that more data is (OR will be very soon) available in the buffer. 1126 // This implies it has been added to whatever position sceAtracGetStreamDataInfo would indicate. 1127 // 1128 // The total size of the buffer is atrac->bufferMaxSize_. 1129 static u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd) { 1130 Atrac *atrac = getAtrac(atracID); 1131 u32 err = AtracValidateManaged(atrac); 1132 if (err != 0) { 1133 // Already logged. 1134 return err; 1135 } 1136 1137 if (atrac->bufferState_ == ATRAC_STATUS_ALL_DATA_LOADED) { 1138 // Let's avoid spurious warnings. Some games call this with 0 which is pretty harmless. 1139 if (bytesToAdd == 0) 1140 return hleLogDebug(ME, ATRAC_ERROR_ALL_DATA_LOADED, "stream entirely loaded"); 1141 return hleLogWarning(ME, ATRAC_ERROR_ALL_DATA_LOADED, "stream entirely loaded"); 1142 } 1143 1144 u32 readOffset; 1145 atrac->CalculateStreamInfo(&readOffset); 1146 1147 if (bytesToAdd > atrac->first_.writableBytes) 1148 return hleLogWarning(ME, ATRAC_ERROR_ADD_DATA_IS_TOO_BIG, "too many bytes"); 1149 1150 if (bytesToAdd > 0) { 1151 atrac->first_.fileoffset = readOffset; 1152 int addbytes = std::min(bytesToAdd, atrac->first_.filesize - atrac->first_.fileoffset); 1153 if (!atrac->ignoreDataBuf_) { 1154 Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, atrac->first_.addr + atrac->first_.offset, addbytes, "AtracAddStreamData"); 1155 } 1156 atrac->first_.fileoffset += addbytes; 1157 } 1158 atrac->first_.size += bytesToAdd; 1159 if (atrac->first_.size >= atrac->first_.filesize) { 1160 atrac->first_.size = atrac->first_.filesize; 1161 if (atrac->bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER) 1162 atrac->bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED; 1163 if (atrac->context_.IsValid()) { 1164 _AtracGenerateContext(atrac); 1165 } 1166 } 1167 1168 atrac->first_.offset += bytesToAdd; 1169 atrac->bufferValidBytes_ += bytesToAdd; 1170 1171 return hleLogSuccessI(ME, 0); 1172 } 1173 1174 u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, int *remains) { 1175 Atrac *atrac = getAtrac(atracID); 1176 1177 u32 ret = 0; 1178 if (atrac == NULL) { 1179 ret = ATRAC_ERROR_BAD_ATRACID; 1180 } else if (!atrac->dataBuf_) { 1181 ret = ATRAC_ERROR_NO_DATA; 1182 } else { 1183 int loopNum = atrac->loopNum_; 1184 if (atrac->bufferState_ == ATRAC_STATUS_FOR_SCESAS) { 1185 // TODO: Might need more testing. 1186 loopNum = 0; 1187 } 1188 1189 // We already passed the end - return an error (many games check for this.) 1190 if (atrac->currentSample_ >= atrac->endSample_ && loopNum == 0) { 1191 *SamplesNum = 0; 1192 *finish = 1; 1193 ret = ATRAC_ERROR_ALL_DATA_DECODED; 1194 } else { 1195 // TODO: This isn't at all right, but at least it makes the music "last" some time. 1196 u32 numSamples = 0; 1197 1198 // It seems like the PSP aligns the sample position to 0x800...? 1199 int offsetSamples = atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); 1200 int skipSamples = 0; 1201 u32 maxSamples = atrac->endSample_ + 1 - atrac->currentSample_; 1202 u32 unalignedSamples = (offsetSamples + atrac->currentSample_) % atrac->SamplesPerFrame(); 1203 if (unalignedSamples != 0) { 1204 // We're off alignment, possibly due to a loop. Force it back on. 1205 maxSamples = atrac->SamplesPerFrame() - unalignedSamples; 1206 skipSamples = unalignedSamples; 1207 } 1208 1209 if (skipSamples != 0 && atrac->bufferHeaderSize_ == 0) { 1210 // Skip the initial frame used to load state for the looped frame. 1211 // TODO: We will want to actually read this in. 1212 atrac->ConsumeFrame(); 1213 } 1214 1215 if (!atrac->failedDecode_ && (atrac->codecType_ == PSP_MODE_AT_3 || atrac->codecType_ == PSP_MODE_AT_3_PLUS)) { 1216 atrac->SeekToSample(atrac->currentSample_); 1217 1218 AtracDecodeResult res = ATDECODE_FEEDME; 1219 while (atrac->FillPacket(-skipSamples)) { 1220 uint32_t packetAddr = atrac->CurBufferAddress(-skipSamples); 1221 int packetSize = atrac->packet_->size; 1222 res = atrac->DecodePacket(); 1223 if (res == ATDECODE_FAILED) { 1224 *SamplesNum = 0; 1225 *finish = 1; 1226 return ATRAC_ERROR_ALL_DATA_DECODED; 1227 } 1228 1229 if (res == ATDECODE_GOTFRAME) { 1230 #ifdef USE_FFMPEG 1231 // got a frame 1232 int skipped = std::min(skipSamples, atrac->frame_->nb_samples); 1233 skipSamples -= skipped; 1234 numSamples = atrac->frame_->nb_samples - skipped; 1235 1236 // If we're at the end, clamp to samples we want. It always returns a full chunk. 1237 numSamples = std::min(maxSamples, numSamples); 1238 1239 if (skipped > 0 && numSamples == 0) { 1240 // Wait for the next one. 1241 res = ATDECODE_FEEDME; 1242 } 1243 1244 if (outbuf != NULL && numSamples != 0) { 1245 int inbufOffset = 0; 1246 if (skipped != 0) { 1247 AVSampleFormat fmt = (AVSampleFormat)atrac->frame_->format; 1248 // We want the offset per channel. 1249 inbufOffset = av_samples_get_buffer_size(NULL, 1, skipped, fmt, 1); 1250 } 1251 1252 u8 *out = outbuf; 1253 const u8 *inbuf[2] = { 1254 atrac->frame_->extended_data[0] + inbufOffset, 1255 atrac->frame_->extended_data[1] + inbufOffset, 1256 }; 1257 int avret = swr_convert(atrac->swrCtx_, &out, numSamples, inbuf, numSamples); 1258 if (outbufPtr != 0) { 1259 u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16); 1260 if (packetAddr != 0 && MemBlockInfoDetailed()) { 1261 const std::string tag = "AtracDecode/" + GetMemWriteTagAt(packetAddr, packetSize); 1262 NotifyMemInfo(MemBlockFlags::READ, packetAddr, packetSize, tag.c_str(), tag.size()); 1263 NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, tag.c_str(), tag.size()); 1264 } else { 1265 NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, "AtracDecode"); 1266 } 1267 } 1268 if (avret < 0) { 1269 ERROR_LOG(ME, "swr_convert: Error while converting %d", avret); 1270 } 1271 } 1272 #endif // USE_FFMPEG 1273 } 1274 if (res == ATDECODE_GOTFRAME || res == ATDECODE_BADFRAME) { 1275 // We only want one frame per call, let's continue the next time. 1276 break; 1277 } 1278 } 1279 1280 if (res != ATDECODE_GOTFRAME && atrac->currentSample_ < atrac->endSample_) { 1281 // Never got a frame. We may have dropped a GHA frame or otherwise have a bug. 1282 // For now, let's try to provide an extra "frame" if possible so games don't infinite loop. 1283 if (atrac->FileOffsetBySample(atrac->currentSample_) < atrac->first_.filesize) { 1284 numSamples = std::min(maxSamples, atrac->SamplesPerFrame()); 1285 u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16); 1286 if (outbuf != nullptr) { 1287 memset(outbuf, 0, outBytes); 1288 NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, "AtracDecode"); 1289 } 1290 } 1291 } 1292 } 1293 1294 *SamplesNum = numSamples; 1295 // update current sample and decodePos 1296 atrac->currentSample_ += numSamples; 1297 atrac->decodePos_ = atrac->DecodePosBySample(atrac->currentSample_); 1298 1299 atrac->ConsumeFrame(); 1300 1301 int finishFlag = 0; 1302 // TODO: Verify. 1303 bool hitEnd = atrac->currentSample_ >= atrac->endSample_ || (numSamples == 0 && atrac->first_.size >= atrac->first_.filesize); 1304 int loopEndAdjusted = atrac->loopEndSample_ - atrac->FirstOffsetExtra() - atrac->firstSampleOffset_; 1305 if ((hitEnd || atrac->currentSample_ > loopEndAdjusted) && loopNum != 0) { 1306 atrac->SeekToSample(atrac->loopStartSample_ - atrac->FirstOffsetExtra() - atrac->firstSampleOffset_); 1307 if (atrac->bufferState_ != ATRAC_STATUS_FOR_SCESAS) { 1308 if (atrac->loopNum_ > 0) 1309 atrac->loopNum_--; 1310 } 1311 if ((atrac->bufferState_ & ATRAC_STATUS_STREAMED_MASK) == ATRAC_STATUS_STREAMED_MASK) { 1312 // Whatever bytes we have left were added from the loop. 1313 u32 loopOffset = atrac->FileOffsetBySample(atrac->loopStartSample_ - atrac->FirstOffsetExtra() - atrac->firstSampleOffset_ - atrac->SamplesPerFrame() * 2); 1314 // TODO: Hmm, need to manage the buffer better. But don't move fileoffset if we already have valid data. 1315 if (loopOffset > atrac->first_.fileoffset || loopOffset + atrac->bufferValidBytes_ < atrac->first_.fileoffset) { 1316 // Skip the initial frame at the start. 1317 atrac->first_.fileoffset = atrac->FileOffsetBySample(atrac->loopStartSample_ - atrac->FirstOffsetExtra() - atrac->firstSampleOffset_ - atrac->SamplesPerFrame() * 2); 1318 } 1319 } 1320 } else if (hitEnd) { 1321 finishFlag = 1; 1322 1323 // Still move forward, so we know that we've read everything. 1324 // This seems to be reflected in the context as well. 1325 atrac->currentSample_ += atrac->SamplesPerFrame() - numSamples; 1326 } 1327 1328 *finish = finishFlag; 1329 *remains = atrac->RemainingFrames(); 1330 } 1331 if (atrac->context_.IsValid()) { 1332 // refresh context_ 1333 _AtracGenerateContext(atrac); 1334 } 1335 } 1336 1337 return ret; 1338 } 1339 1340 static u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishFlagAddr, u32 remainAddr) { 1341 // Note that outAddr being null is completely valid here, used to skip data. 1342 1343 u32 numSamples = 0; 1344 u32 finish = 0; 1345 int remains = 0; 1346 int ret = _AtracDecodeData(atracID, Memory::GetPointer(outAddr), outAddr, &numSamples, &finish, &remains); 1347 if (ret != (int)ATRAC_ERROR_BAD_ATRACID && ret != (int)ATRAC_ERROR_NO_DATA) { 1348 if (Memory::IsValidAddress(numSamplesAddr)) 1349 Memory::Write_U32(numSamples, numSamplesAddr); 1350 if (Memory::IsValidAddress(finishFlagAddr)) 1351 Memory::Write_U32(finish, finishFlagAddr); 1352 // On error, no remaining frame value is written. 1353 if (ret == 0 && Memory::IsValidAddress(remainAddr)) 1354 Memory::Write_U32(remains, remainAddr); 1355 } 1356 DEBUG_LOG(ME, "%08x=sceAtracDecodeData(%i, %08x, %08x[%08x], %08x[%08x], %08x[%d])", ret, atracID, outAddr, 1357 numSamplesAddr, numSamples, 1358 finishFlagAddr, finish, 1359 remainAddr, remains); 1360 if (!ret) { 1361 // decode data successfully, delay thread 1362 return hleDelayResult(ret, "atrac decode data", atracDecodeDelay); 1363 } 1364 return ret; 1365 } 1366 1367 static u32 sceAtracEndEntry() { 1368 ERROR_LOG_REPORT(ME, "UNIMPL sceAtracEndEntry()"); 1369 return 0; 1370 } 1371 1372 static void AtracGetResetBufferInfo(Atrac *atrac, AtracResetBufferInfo *bufferInfo, int sample) { 1373 if (atrac->bufferState_ == ATRAC_STATUS_ALL_DATA_LOADED) { 1374 bufferInfo->first.writePosPtr = atrac->first_.addr; 1375 // Everything is loaded, so nothing needs to be read. 1376 bufferInfo->first.writableBytes = 0; 1377 bufferInfo->first.minWriteBytes = 0; 1378 bufferInfo->first.filePos = 0; 1379 } else if (atrac->bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER) { 1380 // Here the message is: you need to read at least this many bytes to get to that position. 1381 // This is because we're filling the buffer start to finish, not streaming. 1382 bufferInfo->first.writePosPtr = atrac->first_.addr + atrac->first_.size; 1383 bufferInfo->first.writableBytes = atrac->first_.filesize - atrac->first_.size; 1384 int minWriteBytes = atrac->FileOffsetBySample(sample) - atrac->first_.size; 1385 if (minWriteBytes > 0) { 1386 bufferInfo->first.minWriteBytes = minWriteBytes; 1387 } else { 1388 bufferInfo->first.minWriteBytes = 0; 1389 } 1390 bufferInfo->first.filePos = atrac->first_.size; 1391 } else { 1392 // This is without the sample offset. The file offset also includes the previous batch of samples? 1393 int sampleFileOffset = atrac->FileOffsetBySample(sample - atrac->firstSampleOffset_ - atrac->SamplesPerFrame()); 1394 1395 // Update the writable bytes. When streaming, this is just the number of bytes until the end. 1396 const u32 bufSizeAligned = (atrac->bufferMaxSize_ / atrac->bytesPerFrame_) * atrac->bytesPerFrame_; 1397 const int needsMoreFrames = atrac->FirstOffsetExtra(); 1398 1399 bufferInfo->first.writePosPtr = atrac->first_.addr; 1400 bufferInfo->first.writableBytes = std::min(atrac->first_.filesize - sampleFileOffset, bufSizeAligned); 1401 if (((sample + atrac->firstSampleOffset_) % (int)atrac->SamplesPerFrame()) >= (int)atrac->SamplesPerFrame() - needsMoreFrames) { 1402 // Not clear why, but it seems it wants a bit extra in case the sample is late? 1403 bufferInfo->first.minWriteBytes = atrac->bytesPerFrame_ * 3; 1404 } else { 1405 bufferInfo->first.minWriteBytes = atrac->bytesPerFrame_ * 2; 1406 } 1407 if ((u32)sample < (u32)atrac->firstSampleOffset_ && sampleFileOffset != atrac->dataOff_) { 1408 sampleFileOffset -= atrac->bytesPerFrame_; 1409 } 1410 bufferInfo->first.filePos = sampleFileOffset; 1411 1412 if (atrac->second_.size != 0) { 1413 // TODO: We have a second buffer. Within it, minWriteBytes should be zero. 1414 // The filePos should be after the end of the second buffer (or zero.) 1415 // We actually need to ensure we READ from the second buffer before implementing that. 1416 } 1417 } 1418 1419 // It seems like this is always the same as the first buffer's pos, weirdly. 1420 bufferInfo->second.writePosPtr = atrac->first_.addr; 1421 // Reset never needs a second buffer write, since the loop is in a fixed place. 1422 bufferInfo->second.writableBytes = 0; 1423 bufferInfo->second.minWriteBytes = 0; 1424 bufferInfo->second.filePos = 0; 1425 } 1426 1427 // Obtains information about what needs to be in the buffer to seek (or "reset") 1428 // Generally called by games right before calling sceAtracResetPlayPosition(). 1429 static u32 sceAtracGetBufferInfoForResetting(int atracID, int sample, u32 bufferInfoAddr) { 1430 auto bufferInfo = PSPPointer<AtracResetBufferInfo>::Create(bufferInfoAddr); 1431 1432 Atrac *atrac = getAtrac(atracID); 1433 u32 err = AtracValidateManaged(atrac); 1434 if (err != 0) { 1435 // Already logged. 1436 return err; 1437 } 1438 1439 if (!bufferInfo.IsValid()) { 1440 return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid buffer, should crash"); 1441 } else if (atrac->bufferState_ == ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER && atrac->second_.size == 0) { 1442 return hleReportError(ME, ATRAC_ERROR_SECOND_BUFFER_NEEDED, "no second buffer"); 1443 } else if ((u32)sample + atrac->firstSampleOffset_ > (u32)atrac->endSample_ + atrac->firstSampleOffset_) { 1444 return hleLogWarning(ME, ATRAC_ERROR_BAD_SAMPLE, "invalid sample position"); 1445 } else { 1446 AtracGetResetBufferInfo(atrac, bufferInfo, sample); 1447 1448 return hleLogSuccessInfoI(ME, 0); 1449 } 1450 } 1451 1452 static u32 sceAtracGetBitrate(int atracID, u32 outBitrateAddr) { 1453 Atrac *atrac = getAtrac(atracID); 1454 if (!atrac) { 1455 ERROR_LOG(ME, "sceAtracGetBitrate(%i, %08x): bad atrac ID", atracID, outBitrateAddr); 1456 return ATRAC_ERROR_BAD_ATRACID; 1457 } else if (!atrac->dataBuf_) { 1458 ERROR_LOG(ME, "sceAtracGetBitrate(%i, %08x): no data", atracID, outBitrateAddr); 1459 return ATRAC_ERROR_NO_DATA; 1460 } else { 1461 atrac->bitrate_ = (atrac->bytesPerFrame_ * 352800) / 1000; 1462 if (atrac->codecType_ == PSP_MODE_AT_3_PLUS) 1463 atrac->bitrate_ = ((atrac->bitrate_ >> 11) + 8) & 0xFFFFFFF0; 1464 else 1465 atrac->bitrate_ = (atrac->bitrate_ + 511) >> 10; 1466 if (Memory::IsValidAddress(outBitrateAddr)) { 1467 Memory::Write_U32(atrac->bitrate_, outBitrateAddr); 1468 DEBUG_LOG(ME, "sceAtracGetBitrate(%i, %08x[%d])", atracID, outBitrateAddr, atrac->bitrate_); 1469 } 1470 else 1471 DEBUG_LOG_REPORT(ME, "sceAtracGetBitrate(%i, %08x[%d]) invalid address", atracID, outBitrateAddr, atrac->bitrate_); 1472 } 1473 return 0; 1474 } 1475 1476 static u32 sceAtracGetChannel(int atracID, u32 channelAddr) { 1477 Atrac *atrac = getAtrac(atracID); 1478 if (!atrac) { 1479 ERROR_LOG(ME, "sceAtracGetChannel(%i, %08x): bad atrac ID", atracID, channelAddr); 1480 return ATRAC_ERROR_BAD_ATRACID; 1481 } else if (!atrac->dataBuf_) { 1482 ERROR_LOG(ME, "sceAtracGetChannel(%i, %08x): no data", atracID, channelAddr); 1483 return ATRAC_ERROR_NO_DATA; 1484 } else { 1485 if (Memory::IsValidAddress(channelAddr)){ 1486 Memory::Write_U32(atrac->channels_, channelAddr); 1487 DEBUG_LOG(ME, "sceAtracGetChannel(%i, %08x[%d])", atracID, channelAddr, atrac->channels_); 1488 } 1489 else 1490 DEBUG_LOG_REPORT(ME, "sceAtracGetChannel(%i, %08x[%d]) invalid address", atracID, channelAddr, atrac->channels_); 1491 } 1492 return 0; 1493 } 1494 1495 static u32 sceAtracGetLoopStatus(int atracID, u32 loopNumAddr, u32 statusAddr) { 1496 Atrac *atrac = getAtrac(atracID); 1497 if (!atrac) { 1498 ERROR_LOG(ME, "sceAtracGetLoopStatus(%i, %08x, %08x): bad atrac ID", atracID, loopNumAddr, statusAddr); 1499 return ATRAC_ERROR_BAD_ATRACID; 1500 } else if (!atrac->dataBuf_) { 1501 ERROR_LOG(ME, "sceAtracGetLoopStatus(%i, %08x, %08x): no data", atracID, loopNumAddr, statusAddr); 1502 return ATRAC_ERROR_NO_DATA; 1503 } else { 1504 DEBUG_LOG(ME, "sceAtracGetLoopStatus(%i, %08x, %08x)", atracID, loopNumAddr, statusAddr); 1505 if (Memory::IsValidAddress(loopNumAddr)) 1506 Memory::Write_U32(atrac->loopNum_, loopNumAddr); 1507 // return audio's loopinfo in at3 file 1508 if (Memory::IsValidAddress(statusAddr)) { 1509 if (atrac->loopinfo_.size() > 0) 1510 Memory::Write_U32(1, statusAddr); 1511 else 1512 Memory::Write_U32(0, statusAddr); 1513 } 1514 } 1515 return 0; 1516 } 1517 1518 static u32 sceAtracGetInternalErrorInfo(int atracID, u32 errorAddr) { 1519 Atrac *atrac = getAtrac(atracID); 1520 if (!atrac) { 1521 ERROR_LOG(ME, "sceAtracGetInternalErrorInfo(%i, %08x): bad atrac ID", atracID, errorAddr); 1522 return ATRAC_ERROR_BAD_ATRACID; 1523 } else if (!atrac->dataBuf_) { 1524 WARN_LOG(ME, "sceAtracGetInternalErrorInfo(%i, %08x): no data", atracID, errorAddr); 1525 return ATRAC_ERROR_NO_DATA; 1526 } else { 1527 ERROR_LOG(ME, "UNIMPL sceAtracGetInternalErrorInfo(%i, %08x)", atracID, errorAddr); 1528 if (Memory::IsValidAddress(errorAddr)) 1529 Memory::Write_U32(0, errorAddr); 1530 } 1531 return 0; 1532 } 1533 1534 static u32 sceAtracGetMaxSample(int atracID, u32 maxSamplesAddr) { 1535 Atrac *atrac = getAtrac(atracID); 1536 if (!atrac) { 1537 ERROR_LOG(ME, "sceAtracGetMaxSample(%i, %08x): bad atrac ID", atracID, maxSamplesAddr); 1538 return ATRAC_ERROR_BAD_ATRACID; 1539 } else if (!atrac->dataBuf_) { 1540 ERROR_LOG(ME, "sceAtracGetMaxSample(%i, %08x): no data", atracID, maxSamplesAddr); 1541 return ATRAC_ERROR_NO_DATA; 1542 } else { 1543 DEBUG_LOG(ME, "sceAtracGetMaxSample(%i, %08x)", atracID, maxSamplesAddr); 1544 if (Memory::IsValidAddress(maxSamplesAddr)) { 1545 Memory::Write_U32(atrac->SamplesPerFrame(), maxSamplesAddr); 1546 } 1547 } 1548 return 0; 1549 } 1550 1551 static u32 sceAtracGetNextDecodePosition(int atracID, u32 outposAddr) { 1552 Atrac *atrac = getAtrac(atracID); 1553 if (!atrac) { 1554 ERROR_LOG(ME, "sceAtracGetNextDecodePosition(%i, %08x): bad atrac ID", atracID, outposAddr); 1555 return ATRAC_ERROR_BAD_ATRACID; 1556 } else if (!atrac->dataBuf_) { 1557 ERROR_LOG(ME, "sceAtracGetNextDecodePosition(%i, %08x): no data", atracID, outposAddr); 1558 return ATRAC_ERROR_NO_DATA; 1559 } else { 1560 DEBUG_LOG(ME, "sceAtracGetNextDecodePosition(%i, %08x)", atracID, outposAddr); 1561 if (atrac->currentSample_ >= atrac->endSample_) { 1562 if (Memory::IsValidAddress(outposAddr)) 1563 Memory::Write_U32(0, outposAddr); 1564 return ATRAC_ERROR_ALL_DATA_DECODED; 1565 } else { 1566 if (Memory::IsValidAddress(outposAddr)) 1567 Memory::Write_U32(atrac->currentSample_, outposAddr); 1568 } 1569 } 1570 return 0; 1571 } 1572 1573 static u32 sceAtracGetNextSample(int atracID, u32 outNAddr) { 1574 Atrac *atrac = getAtrac(atracID); 1575 if (!atrac) { 1576 ERROR_LOG(ME, "sceAtracGetNextSample(%i, %08x): bad atrac ID", atracID, outNAddr); 1577 return ATRAC_ERROR_BAD_ATRACID; 1578 } else if (!atrac->dataBuf_) { 1579 ERROR_LOG(ME, "sceAtracGetNextSample(%i, %08x): no data", atracID, outNAddr); 1580 return ATRAC_ERROR_NO_DATA; 1581 } else { 1582 if (atrac->currentSample_ >= atrac->endSample_) { 1583 if (Memory::IsValidAddress(outNAddr)) 1584 Memory::Write_U32(0, outNAddr); 1585 DEBUG_LOG(ME, "sceAtracGetNextSample(%i, %08x): 0 samples left", atracID, outNAddr); 1586 return 0; 1587 } else { 1588 // It seems like the PSP aligns the sample position to 0x800...? 1589 u32 skipSamples = atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); 1590 u32 firstSamples = (atrac->SamplesPerFrame() - skipSamples) % atrac->SamplesPerFrame(); 1591 u32 numSamples = atrac->endSample_ + 1 - atrac->currentSample_; 1592 if (atrac->currentSample_ == 0 && firstSamples != 0) { 1593 numSamples = firstSamples; 1594 } 1595 u32 unalignedSamples = (skipSamples + atrac->currentSample_) % atrac->SamplesPerFrame(); 1596 if (unalignedSamples != 0) { 1597 // We're off alignment, possibly due to a loop. Force it back on. 1598 numSamples = atrac->SamplesPerFrame() - unalignedSamples; 1599 } 1600 if (numSamples > atrac->SamplesPerFrame()) 1601 numSamples = atrac->SamplesPerFrame(); 1602 if (Memory::IsValidAddress(outNAddr)) 1603 Memory::Write_U32(numSamples, outNAddr); 1604 DEBUG_LOG(ME, "sceAtracGetNextSample(%i, %08x): %d samples left", atracID, outNAddr, numSamples); 1605 } 1606 } 1607 return 0; 1608 } 1609 1610 // Obtains the number of frames remaining in the buffer which can be decoded. 1611 // When no more data would be needed, this returns a negative number. 1612 static u32 sceAtracGetRemainFrame(int atracID, u32 remainAddr) { 1613 auto remainingFrames = PSPPointer<u32_le>::Create(remainAddr); 1614 1615 Atrac *atrac = getAtrac(atracID); 1616 u32 err = AtracValidateManaged(atrac); 1617 if (err != 0) { 1618 // Already logged. 1619 return err; 1620 } 1621 1622 if (!remainingFrames.IsValid()) { 1623 // Would crash. 1624 return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid remainingFrames pointer"); 1625 } 1626 1627 *remainingFrames = atrac->RemainingFrames(); 1628 return hleLogSuccessI(ME, 0); 1629 } 1630 1631 static u32 sceAtracGetSecondBufferInfo(int atracID, u32 fileOffsetAddr, u32 desiredSizeAddr) { 1632 auto fileOffset = PSPPointer<u32_le>::Create(fileOffsetAddr); 1633 auto desiredSize = PSPPointer<u32_le>::Create(desiredSizeAddr); 1634 1635 Atrac *atrac = getAtrac(atracID); 1636 u32 err = AtracValidateManaged(atrac); 1637 if (err != 0) { 1638 // Already logged. 1639 return err; 1640 } 1641 1642 if (!fileOffset.IsValid() || !desiredSize.IsValid()) { 1643 // Would crash. 1644 return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid addresses"); 1645 } 1646 1647 if (atrac->bufferState_ != ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER) { 1648 // Writes zeroes in this error case. 1649 *fileOffset = 0; 1650 *desiredSize = 0; 1651 return hleLogWarning(ME, ATRAC_ERROR_SECOND_BUFFER_NOT_NEEDED, "not needed"); 1652 } 1653 1654 *fileOffset = atrac->FileOffsetBySample(atrac->loopEndSample_ - atrac->firstSampleOffset_); 1655 *desiredSize = atrac->first_.filesize - *fileOffset; 1656 1657 return hleLogSuccessI(ME, 0); 1658 } 1659 1660 static u32 sceAtracGetSoundSample(int atracID, u32 outEndSampleAddr, u32 outLoopStartSampleAddr, u32 outLoopEndSampleAddr) { 1661 Atrac *atrac = getAtrac(atracID); 1662 u32 err = AtracValidateManaged(atrac); 1663 if (err != 0) { 1664 // Already logged. 1665 return err; 1666 } 1667 1668 auto outEndSample = PSPPointer<u32_le>::Create(outEndSampleAddr); 1669 if (outEndSample.IsValid()) 1670 *outEndSample = atrac->endSample_; 1671 auto outLoopStart = PSPPointer<u32_le>::Create(outLoopStartSampleAddr); 1672 if (outLoopStart.IsValid()) 1673 *outLoopStart = atrac->loopStartSample_ == -1 ? -1 : atrac->loopStartSample_ - atrac->firstSampleOffset_ - atrac->FirstOffsetExtra(); 1674 auto outLoopEnd = PSPPointer<u32_le>::Create(outLoopEndSampleAddr); 1675 if (outLoopEnd.IsValid()) 1676 *outLoopEnd = atrac->loopEndSample_ == -1 ? -1 : atrac->loopEndSample_ - atrac->firstSampleOffset_ - atrac->FirstOffsetExtra(); 1677 1678 if (!outEndSample.IsValid() || !outLoopStart.IsValid() || !outLoopEnd.IsValid()) { 1679 return hleReportError(ME, 0, "invalid address"); 1680 } 1681 return hleLogSuccessI(ME, 0); 1682 } 1683 1684 // Games call this function to get some info for add more stream data, 1685 // such as where the data read from, where the data add to, 1686 // and how many bytes are allowed to add. 1687 static u32 sceAtracGetStreamDataInfo(int atracID, u32 writePtrAddr, u32 writableBytesAddr, u32 readOffsetAddr) { 1688 Atrac *atrac = getAtrac(atracID); 1689 u32 err = AtracValidateManaged(atrac); 1690 if (err != 0) { 1691 // Already logged. 1692 return err; 1693 } 1694 1695 u32 readOffset; 1696 atrac->CalculateStreamInfo(&readOffset); 1697 1698 if (Memory::IsValidAddress(writePtrAddr)) 1699 Memory::Write_U32(atrac->first_.addr + atrac->first_.offset, writePtrAddr); 1700 if (Memory::IsValidAddress(writableBytesAddr)) 1701 Memory::Write_U32(atrac->first_.writableBytes, writableBytesAddr); 1702 if (Memory::IsValidAddress(readOffsetAddr)) 1703 Memory::Write_U32(readOffset, readOffsetAddr); 1704 1705 return hleLogSuccessI(ME, 0); 1706 } 1707 1708 static u32 sceAtracReleaseAtracID(int atracID) { 1709 int result = deleteAtrac(atracID); 1710 if (result < 0) { 1711 return hleLogError(ME, result, "did not exist"); 1712 } 1713 return hleLogSuccessInfoI(ME, result); 1714 } 1715 1716 // This is called when a game wants to seek (or "reset") to a specific position in the audio data. 1717 // Normally, sceAtracGetBufferInfoForResetting() is called to determine how to buffer. 1718 // The game must add sufficient packets to the buffer in order to complete the seek. 1719 static u32 sceAtracResetPlayPosition(int atracID, int sample, int bytesWrittenFirstBuf, int bytesWrittenSecondBuf) { 1720 Atrac *atrac = getAtrac(atracID); 1721 u32 err = AtracValidateManaged(atrac); 1722 if (err != 0) { 1723 // Already logged. 1724 return err; 1725 } 1726 1727 if (atrac->bufferState_ == ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER && atrac->second_.size == 0) { 1728 return hleReportError(ME, ATRAC_ERROR_SECOND_BUFFER_NEEDED, "no second buffer"); 1729 } else if ((u32)sample + atrac->firstSampleOffset_ > (u32)atrac->endSample_ + atrac->firstSampleOffset_) { 1730 return hleLogWarning(ME, ATRAC_ERROR_BAD_SAMPLE, "invalid sample position"); 1731 } else { 1732 // Reuse the same calculation as before. 1733 AtracResetBufferInfo bufferInfo; 1734 AtracGetResetBufferInfo(atrac, &bufferInfo, sample); 1735 1736 if ((u32)bytesWrittenFirstBuf < bufferInfo.first.minWriteBytes || (u32)bytesWrittenFirstBuf > bufferInfo.first.writableBytes) { 1737 return hleLogError(ME, ATRAC_ERROR_BAD_FIRST_RESET_SIZE, "first byte count not in valid range"); 1738 } 1739 if ((u32)bytesWrittenSecondBuf < bufferInfo.second.minWriteBytes || (u32)bytesWrittenSecondBuf > bufferInfo.second.writableBytes) { 1740 return hleLogError(ME, ATRAC_ERROR_BAD_SECOND_RESET_SIZE, "second byte count not in valid range"); 1741 } 1742 1743 if (atrac->bufferState_ == ATRAC_STATUS_ALL_DATA_LOADED) { 1744 // Always adds zero bytes. 1745 } else if (atrac->bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER) { 1746 // Okay, it's a valid number of bytes. Let's set them up. 1747 if (bytesWrittenFirstBuf != 0) { 1748 if (!atrac->ignoreDataBuf_) { 1749 Memory::Memcpy(atrac->dataBuf_ + atrac->first_.size, atrac->first_.addr + atrac->first_.size, bytesWrittenFirstBuf, "AtracResetPlayPosition"); 1750 } 1751 atrac->first_.fileoffset += bytesWrittenFirstBuf; 1752 atrac->first_.size += bytesWrittenFirstBuf; 1753 atrac->first_.offset += bytesWrittenFirstBuf; 1754 } 1755 1756 // Did we transition to a full buffer? 1757 if (atrac->first_.size >= atrac->first_.filesize) { 1758 atrac->first_.size = atrac->first_.filesize; 1759 if (atrac->bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER) 1760 atrac->bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED; 1761 } 1762 } else { 1763 if (bufferInfo.first.filePos > atrac->first_.filesize) { 1764 return hleDelayResult(hleLogError(ME, ATRAC_ERROR_API_FAIL, "invalid file position"), "reset play pos", 200); 1765 } 1766 1767 // Move the offset to the specified position. 1768 atrac->first_.fileoffset = bufferInfo.first.filePos; 1769 1770 if (bytesWrittenFirstBuf != 0) { 1771 if (!atrac->ignoreDataBuf_) { 1772 Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, atrac->first_.addr, bytesWrittenFirstBuf, "AtracResetPlayPosition"); 1773 } 1774 atrac->first_.fileoffset += bytesWrittenFirstBuf; 1775 } 1776 atrac->first_.size = atrac->first_.fileoffset; 1777 atrac->first_.offset = bytesWrittenFirstBuf; 1778 1779 atrac->bufferHeaderSize_ = 0; 1780 atrac->bufferPos_ = atrac->bytesPerFrame_; 1781 atrac->bufferValidBytes_ = bytesWrittenFirstBuf - atrac->bufferPos_; 1782 } 1783 1784 if (atrac->codecType_ == PSP_MODE_AT_3 || atrac->codecType_ == PSP_MODE_AT_3_PLUS) { 1785 atrac->SeekToSample(sample); 1786 } 1787 1788 if (atrac->context_.IsValid()) { 1789 _AtracGenerateContext(atrac); 1790 } 1791 1792 return hleDelayResult(hleLogSuccessInfoI(ME, 0), "reset play pos", 3000); 1793 } 1794 } 1795 1796 #ifdef USE_FFMPEG 1797 static int __AtracUpdateOutputMode(Atrac *atrac, int wanted_channels) { 1798 if (atrac->swrCtx_ && atrac->outputChannels_ == wanted_channels) 1799 return 0; 1800 atrac->outputChannels_ = wanted_channels; 1801 int64_t wanted_channel_layout = av_get_default_channel_layout(wanted_channels); 1802 int64_t dec_channel_layout = av_get_default_channel_layout(atrac->channels_); 1803 1804 atrac->swrCtx_ = 1805 swr_alloc_set_opts 1806 ( 1807 atrac->swrCtx_, 1808 wanted_channel_layout, 1809 AV_SAMPLE_FMT_S16, 1810 atrac->codecCtx_->sample_rate, 1811 dec_channel_layout, 1812 atrac->codecCtx_->sample_fmt, 1813 atrac->codecCtx_->sample_rate, 1814 0, 1815 NULL 1816 ); 1817 if (!atrac->swrCtx_) { 1818 ERROR_LOG(ME, "swr_alloc_set_opts: Could not allocate resampler context"); 1819 return -1; 1820 } 1821 if (swr_init(atrac->swrCtx_) < 0) { 1822 ERROR_LOG(ME, "swr_init: Failed to initialize the resampling context"); 1823 return -1; 1824 } 1825 return 0; 1826 } 1827 #endif // USE_FFMPEG 1828 1829 int __AtracSetContext(Atrac *atrac) { 1830 #ifdef USE_FFMPEG 1831 InitFFmpeg(); 1832 1833 AVCodecID ff_codec; 1834 if (atrac->codecType_ == PSP_MODE_AT_3) { 1835 ff_codec = AV_CODEC_ID_ATRAC3; 1836 } else if (atrac->codecType_ == PSP_MODE_AT_3_PLUS) { 1837 ff_codec = AV_CODEC_ID_ATRAC3P; 1838 } else { 1839 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "unknown codec type in set context"); 1840 } 1841 1842 const AVCodec *codec = avcodec_find_decoder(ff_codec); 1843 atrac->codecCtx_ = avcodec_alloc_context3(codec); 1844 1845 if (atrac->codecType_ == PSP_MODE_AT_3) { 1846 // For ATRAC3, we need the "extradata" in the RIFF header. 1847 atrac->codecCtx_->extradata = (uint8_t *)av_mallocz(14); 1848 atrac->codecCtx_->extradata_size = 14; 1849 1850 // We don't pull this from the RIFF so that we can support OMA also. 1851 // The only thing that changes are the jointStereo_ values. 1852 atrac->codecCtx_->extradata[0] = 1; 1853 atrac->codecCtx_->extradata[3] = atrac->channels_ << 3; 1854 atrac->codecCtx_->extradata[6] = atrac->jointStereo_; 1855 atrac->codecCtx_->extradata[8] = atrac->jointStereo_; 1856 atrac->codecCtx_->extradata[10] = 1; 1857 } 1858 1859 // Appears we need to force mono in some cases. (See CPkmn's comments in issue #4248) 1860 if (atrac->channels_ == 1) { 1861 atrac->codecCtx_->channels = 1; 1862 atrac->codecCtx_->channel_layout = AV_CH_LAYOUT_MONO; 1863 } else if (atrac->channels_ == 2) { 1864 atrac->codecCtx_->channels = 2; 1865 atrac->codecCtx_->channel_layout = AV_CH_LAYOUT_STEREO; 1866 } else { 1867 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "unknown channel layout in set context"); 1868 } 1869 1870 // Explicitly set the block_align value (needed by newer FFmpeg versions, see #5772.) 1871 if (atrac->codecCtx_->block_align == 0) { 1872 atrac->codecCtx_->block_align = atrac->bytesPerFrame_; 1873 } 1874 // Only one supported, it seems? 1875 atrac->codecCtx_->sample_rate = 44100; 1876 1877 atrac->codecCtx_->request_sample_fmt = AV_SAMPLE_FMT_S16; 1878 int ret; 1879 if ((ret = avcodec_open2(atrac->codecCtx_, codec, nullptr)) < 0) { 1880 // This can mean that the frame size is wrong or etc. 1881 return hleLogError(ME, ATRAC_ERROR_BAD_CODEC_PARAMS, "failed to open decoder %d", ret); 1882 } 1883 1884 if ((ret = __AtracUpdateOutputMode(atrac, atrac->outputChannels_)) < 0) 1885 return hleLogError(ME, ret, "failed to set the output mode"); 1886 1887 // alloc audio frame 1888 atrac->frame_ = av_frame_alloc(); 1889 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 1890 atrac->packet_ = av_packet_alloc(); 1891 #else 1892 atrac->packet_ = new AVPacket; 1893 av_init_packet(atrac->packet_); 1894 atrac->packet_->data = nullptr; 1895 atrac->packet_->size = 0; 1896 #endif 1897 // reinit decodePos, because ffmpeg had changed it. 1898 atrac->decodePos_ = 0; 1899 #endif 1900 1901 return 0; 1902 } 1903 1904 static int _AtracSetData(Atrac *atrac, u32 buffer, u32 readSize, u32 bufferSize, int successCode = 0) { 1905 atrac->first_.addr = buffer; 1906 atrac->first_.size = readSize; 1907 1908 if (atrac->first_.size > atrac->first_.filesize) 1909 atrac->first_.size = atrac->first_.filesize; 1910 atrac->first_.fileoffset = atrac->first_.size; 1911 1912 // got the size of temp buf, and calculate offset 1913 atrac->bufferMaxSize_ = bufferSize; 1914 atrac->first_.offset = atrac->first_.size; 1915 1916 // some games may reuse an atracID for playing sound 1917 atrac->ResetData(); 1918 atrac->SetBufferState(); 1919 1920 if (atrac->codecType_ != PSP_MODE_AT_3 && atrac->codecType_ != PSP_MODE_AT_3_PLUS) { 1921 // Shouldn't have gotten here, Analyze() checks this. 1922 atrac->bufferState_ = ATRAC_STATUS_NO_DATA; 1923 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "unexpected codec type in set data"); 1924 } 1925 1926 if (atrac->bufferState_ == ATRAC_STATUS_ALL_DATA_LOADED || atrac->bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER) { 1927 // This says, don't use the dataBuf_ array, use the PSP RAM. 1928 // This way, games can load data async into the buffer, and it still works. 1929 // TODO: Support this always, even for streaming. 1930 atrac->ignoreDataBuf_ = true; 1931 } 1932 if (atrac->bufferState_ == ATRAC_STATUS_STREAMED_WITHOUT_LOOP || atrac->bufferState_ == ATRAC_STATUS_STREAMED_LOOP_FROM_END || atrac->bufferState_ == ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER) { 1933 atrac->bufferHeaderSize_ = atrac->dataOff_; 1934 atrac->bufferPos_ = atrac->dataOff_ + atrac->bytesPerFrame_; 1935 atrac->bufferValidBytes_ = atrac->first_.size - atrac->bufferPos_; 1936 } 1937 1938 const char *codecName = atrac->codecType_ == PSP_MODE_AT_3 ? "atrac3" : "atrac3+"; 1939 const char *channelName = atrac->channels_ == 1 ? "mono" : "stereo"; 1940 1941 atrac->dataBuf_ = new u8[atrac->first_.filesize]; 1942 if (!atrac->ignoreDataBuf_) { 1943 u32 copybytes = std::min(bufferSize, atrac->first_.filesize); 1944 Memory::Memcpy(atrac->dataBuf_, buffer, copybytes, "AtracSetData"); 1945 } 1946 int ret = __AtracSetContext(atrac); 1947 if (ret < 0) { 1948 // Already logged. 1949 return ret; 1950 } 1951 1952 return hleLogSuccessInfoI(ME, successCode, "%s %s audio", codecName, channelName); 1953 } 1954 1955 static int _AtracSetData(int atracID, u32 buffer, u32 readSize, u32 bufferSize, bool needReturnAtracID = false) { 1956 Atrac *atrac = getAtrac(atracID); 1957 if (!atrac) 1958 return hleLogError(ME, ATRAC_ERROR_BAD_ATRACID, "invalid atrac ID"); 1959 int ret = _AtracSetData(atrac, buffer, readSize, bufferSize, needReturnAtracID ? atracID : 0); 1960 // not sure the real delay time 1961 return hleDelayResult(ret, "atrac set data", 100); 1962 } 1963 1964 static u32 sceAtracSetHalfwayBuffer(int atracID, u32 buffer, u32 readSize, u32 bufferSize) { 1965 Atrac *atrac = getAtrac(atracID); 1966 if (!atrac) { 1967 return hleLogError(ME, ATRAC_ERROR_BAD_ATRACID, "bad atrac ID"); 1968 } 1969 if (readSize > bufferSize) { 1970 return hleLogError(ME, ATRAC_ERROR_INCORRECT_READ_SIZE, "read size too large"); 1971 } 1972 1973 int ret = atrac->Analyze(buffer, readSize); 1974 if (ret < 0) { 1975 // Already logged. 1976 return ret; 1977 } 1978 1979 atrac->outputChannels_ = 2; 1980 return _AtracSetData(atracID, buffer, readSize, bufferSize); 1981 } 1982 1983 static u32 sceAtracSetSecondBuffer(int atracID, u32 secondBuffer, u32 secondBufferSize) { 1984 Atrac *atrac = getAtrac(atracID); 1985 u32 err = AtracValidateManaged(atrac); 1986 if (err != 0) { 1987 // Already logged. 1988 return err; 1989 } 1990 1991 u32 secondFileOffset = atrac->FileOffsetBySample(atrac->loopEndSample_ - atrac->firstSampleOffset_); 1992 u32 desiredSize = atrac->first_.filesize - secondFileOffset; 1993 1994 // 3 seems to be the number of frames required to handle a loop. 1995 if (secondBufferSize < desiredSize && secondBufferSize < (u32)atrac->bytesPerFrame_ * 3) { 1996 return hleReportError(ME, ATRAC_ERROR_SIZE_TOO_SMALL, "too small"); 1997 } 1998 if (atrac->bufferState_ != ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER) { 1999 return hleReportError(ME, ATRAC_ERROR_SECOND_BUFFER_NOT_NEEDED, "not needed"); 2000 } 2001 2002 atrac->second_.addr = secondBuffer; 2003 atrac->second_.size = secondBufferSize; 2004 atrac->second_.fileoffset = secondFileOffset; 2005 2006 return 0; 2007 } 2008 2009 static u32 sceAtracSetData(int atracID, u32 buffer, u32 bufferSize) { 2010 Atrac *atrac = getAtrac(atracID); 2011 if (!atrac) { 2012 return hleLogError(ME, ATRAC_ERROR_BAD_ATRACID, "bad atrac ID"); 2013 } 2014 2015 int ret = atrac->Analyze(buffer, bufferSize); 2016 if (ret < 0) { 2017 // Already logged. 2018 return ret; 2019 } 2020 2021 if (atrac->codecType_ != atracIDTypes[atracID]) { 2022 // TODO: Should this not change the buffer size? 2023 return hleReportError(ME, ATRAC_ERROR_WRONG_CODECTYPE, "atracID uses different codec type than data"); 2024 } 2025 2026 atrac->outputChannels_ = 2; 2027 return _AtracSetData(atracID, buffer, bufferSize, bufferSize); 2028 } 2029 2030 static int sceAtracSetDataAndGetID(u32 buffer, int bufferSize) { 2031 // A large value happens in Tales of VS, and isn't handled somewhere properly as a u32. 2032 // It's impossible for it to be that big anyway, so cap it. 2033 if (bufferSize < 0) { 2034 WARN_LOG(ME, "sceAtracSetDataAndGetID(%08x, %08x): negative bufferSize", buffer, bufferSize); 2035 bufferSize = 0x10000000; 2036 } 2037 2038 Atrac *atrac = new Atrac(); 2039 int ret = atrac->Analyze(buffer, bufferSize); 2040 if (ret < 0) { 2041 // Already logged. 2042 delete atrac; 2043 return ret; 2044 } 2045 int atracID = createAtrac(atrac); 2046 if (atracID < 0) { 2047 delete atrac; 2048 return hleLogError(ME, atracID, "no free ID"); 2049 } 2050 2051 atrac->outputChannels_ = 2; 2052 return _AtracSetData(atracID, buffer, bufferSize, bufferSize, true); 2053 } 2054 2055 static int sceAtracSetHalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 bufferSize) { 2056 if (readSize > bufferSize) { 2057 return hleLogError(ME, ATRAC_ERROR_INCORRECT_READ_SIZE, "read size too large"); 2058 } 2059 Atrac *atrac = new Atrac(); 2060 int ret = atrac->Analyze(buffer, readSize); 2061 if (ret < 0) { 2062 // Already logged. 2063 delete atrac; 2064 return ret; 2065 } 2066 int atracID = createAtrac(atrac); 2067 if (atracID < 0) { 2068 delete atrac; 2069 return hleLogError(ME, atracID, "no free ID"); 2070 } 2071 2072 atrac->outputChannels_ = 2; 2073 return _AtracSetData(atracID, buffer, readSize, bufferSize, true); 2074 } 2075 2076 static u32 sceAtracStartEntry() { 2077 ERROR_LOG_REPORT(ME, "UNIMPL sceAtracStartEntry()"); 2078 return 0; 2079 } 2080 2081 static u32 sceAtracSetLoopNum(int atracID, int loopNum) { 2082 Atrac *atrac = getAtrac(atracID); 2083 if (!atrac) { 2084 ERROR_LOG(ME, "sceAtracSetLoopNum(%i, %i): bad atrac ID", atracID, loopNum); 2085 return ATRAC_ERROR_BAD_ATRACID; 2086 } else if (!atrac->dataBuf_) { 2087 ERROR_LOG(ME, "sceAtracSetLoopNum(%i, %i): no data", atracID, loopNum); 2088 return ATRAC_ERROR_NO_DATA; 2089 } else { 2090 if (atrac->loopinfo_.size() == 0) { 2091 DEBUG_LOG(ME, "sceAtracSetLoopNum(%i, %i): error: no loop information", atracID, loopNum); 2092 return ATRAC_ERROR_NO_LOOP_INFORMATION; 2093 } 2094 // Spammed in MHU 2095 DEBUG_LOG(ME, "sceAtracSetLoopNum(%i, %i)", atracID, loopNum); 2096 atrac->loopNum_ = loopNum; 2097 if (loopNum != 0 && atrac->loopinfo_.size() == 0) { 2098 // Just loop the whole audio 2099 atrac->loopStartSample_ = atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); 2100 atrac->loopEndSample_ = atrac->endSample_ + atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); 2101 } 2102 if (atrac->context_.IsValid()) { 2103 _AtracGenerateContext(atrac); 2104 } 2105 } 2106 return 0; 2107 } 2108 2109 static int sceAtracReinit(int at3Count, int at3plusCount) { 2110 for (int i = 0; i < PSP_NUM_ATRAC_IDS; ++i) { 2111 if (atracIDs[i] != NULL) { 2112 ERROR_LOG_REPORT(ME, "sceAtracReinit(%d, %d): cannot reinit while IDs in use", at3Count, at3plusCount); 2113 return SCE_KERNEL_ERROR_BUSY; 2114 } 2115 } 2116 2117 memset(atracIDTypes, 0, sizeof(atracIDTypes)); 2118 int next = 0; 2119 int space = PSP_NUM_ATRAC_IDS; 2120 2121 // This seems to deinit things. Mostly, it cause a reschedule on next deinit (but -1, -1 does not.) 2122 if (at3Count == 0 && at3plusCount == 0) { 2123 INFO_LOG(ME, "sceAtracReinit(%d, %d): deinit", at3Count, at3plusCount); 2124 atracInited = false; 2125 return hleDelayResult(0, "atrac reinit", 200); 2126 } 2127 2128 // First, ATRAC3+. These IDs seem to cost double (probably memory.) 2129 // Intentionally signed. 9999 tries to allocate, -1 does not. 2130 for (int i = 0; i < at3plusCount; ++i) { 2131 space -= 2; 2132 if (space >= 0) { 2133 atracIDTypes[next++] = PSP_MODE_AT_3_PLUS; 2134 } 2135 } 2136 for (int i = 0; i < at3Count; ++i) { 2137 space -= 1; 2138 if (space >= 0) { 2139 atracIDTypes[next++] = PSP_MODE_AT_3; 2140 } 2141 } 2142 2143 // If we ran out of space, we still initialize some, but return an error. 2144 int result = space >= 0 ? 0 : (int)SCE_KERNEL_ERROR_OUT_OF_MEMORY; 2145 if (atracInited || next == 0) { 2146 INFO_LOG(ME, "sceAtracReinit(%d, %d)", at3Count, at3plusCount); 2147 atracInited = true; 2148 return result; 2149 } else { 2150 INFO_LOG(ME, "sceAtracReinit(%d, %d): init", at3Count, at3plusCount); 2151 atracInited = true; 2152 return hleDelayResult(result, "atrac reinit", 400); 2153 } 2154 } 2155 2156 static int sceAtracGetOutputChannel(int atracID, u32 outputChanPtr) { 2157 Atrac *atrac = getAtrac(atracID); 2158 if (!atrac) { 2159 ERROR_LOG(ME, "sceAtracGetOutputChannel(%i, %08x): bad atrac ID", atracID, outputChanPtr); 2160 return ATRAC_ERROR_BAD_ATRACID; 2161 } else if (!atrac->dataBuf_) { 2162 ERROR_LOG(ME, "sceAtracGetOutputChannel(%i, %08x): no data", atracID, outputChanPtr); 2163 return ATRAC_ERROR_NO_DATA; 2164 } else { 2165 DEBUG_LOG(ME, "sceAtracGetOutputChannel(%i, %08x)", atracID, outputChanPtr); 2166 if (Memory::IsValidAddress(outputChanPtr)) 2167 Memory::Write_U32(atrac->outputChannels_, outputChanPtr); 2168 } 2169 return 0; 2170 } 2171 2172 static int sceAtracIsSecondBufferNeeded(int atracID) { 2173 Atrac *atrac = getAtrac(atracID); 2174 u32 err = AtracValidateManaged(atrac); 2175 if (err != 0) { 2176 // Already logged. 2177 return err; 2178 } 2179 2180 // Note that this returns true whether the buffer is already set or not. 2181 int needed = atrac->bufferState_ == ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER ? 1 : 0; 2182 return hleLogSuccessI(ME, needed); 2183 } 2184 2185 static int sceAtracSetMOutHalfwayBuffer(int atracID, u32 buffer, u32 readSize, u32 bufferSize) { 2186 Atrac *atrac = getAtrac(atracID); 2187 if (!atrac) { 2188 return hleLogError(ME, ATRAC_ERROR_BAD_ATRACID, "bad atrac ID"); 2189 } 2190 if (readSize > bufferSize) { 2191 return hleLogError(ME, ATRAC_ERROR_INCORRECT_READ_SIZE, "read size too large"); 2192 } 2193 2194 int ret = atrac->Analyze(buffer, readSize); 2195 if (ret < 0) { 2196 // Already logged. 2197 return ret; 2198 } 2199 if (atrac->channels_ != 1) { 2200 // It seems it still sets the data. 2201 atrac->outputChannels_ = 2; 2202 _AtracSetData(atrac, buffer, readSize, bufferSize); 2203 return hleReportError(ME, ATRAC_ERROR_NOT_MONO, "not mono data"); 2204 } else { 2205 atrac->outputChannels_ = 1; 2206 ret = _AtracSetData(atracID, buffer, readSize, bufferSize); 2207 } 2208 return ret; 2209 } 2210 2211 // Note: This doesn't seem to be part of any available libatrac3plus library. 2212 static u32 sceAtracSetMOutData(int atracID, u32 buffer, u32 bufferSize) { 2213 Atrac *atrac = getAtrac(atracID); 2214 if (!atrac) { 2215 return hleLogError(ME, ATRAC_ERROR_BAD_ATRACID, "bad atrac ID"); 2216 } 2217 2218 int ret = atrac->Analyze(buffer, bufferSize); 2219 if (ret < 0) { 2220 // Already logged. 2221 return ret; 2222 } 2223 if (atrac->channels_ != 1) { 2224 // It seems it still sets the data. 2225 atrac->outputChannels_ = 2; 2226 _AtracSetData(atrac, buffer, bufferSize, bufferSize); 2227 return hleReportError(ME, ATRAC_ERROR_NOT_MONO, "not mono data"); 2228 } else { 2229 atrac->outputChannels_ = 1; 2230 ret = _AtracSetData(atracID, buffer, bufferSize, bufferSize); 2231 } 2232 return ret; 2233 } 2234 2235 // Note: This doesn't seem to be part of any available libatrac3plus library. 2236 static int sceAtracSetMOutDataAndGetID(u32 buffer, u32 bufferSize) { 2237 Atrac *atrac = new Atrac(); 2238 int ret = atrac->Analyze(buffer, bufferSize); 2239 if (ret < 0) { 2240 // Already logged. 2241 delete atrac; 2242 return ret; 2243 } 2244 if (atrac->channels_ != 1) { 2245 delete atrac; 2246 return hleReportError(ME, ATRAC_ERROR_NOT_MONO, "not mono data"); 2247 } 2248 int atracID = createAtrac(atrac); 2249 if (atracID < 0) { 2250 delete atrac; 2251 return hleLogError(ME, atracID, "no free ID"); 2252 } 2253 2254 atrac->outputChannels_ = 1; 2255 return _AtracSetData(atracID, buffer, bufferSize, bufferSize, true); 2256 } 2257 2258 static int sceAtracSetMOutHalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 bufferSize) { 2259 if (readSize > bufferSize) { 2260 return hleLogError(ME, ATRAC_ERROR_INCORRECT_READ_SIZE, "read size too large"); 2261 } 2262 Atrac *atrac = new Atrac(); 2263 int ret = atrac->Analyze(buffer, readSize); 2264 if (ret < 0) { 2265 // Already logged. 2266 delete atrac; 2267 return ret; 2268 } 2269 if (atrac->channels_ != 1) { 2270 delete atrac; 2271 return hleReportError(ME, ATRAC_ERROR_NOT_MONO, "not mono data"); 2272 } 2273 int atracID = createAtrac(atrac); 2274 if (atracID < 0) { 2275 delete atrac; 2276 return hleLogError(ME, atracID, "no free ID"); 2277 } 2278 2279 atrac->outputChannels_ = 1; 2280 return _AtracSetData(atracID, buffer, readSize, bufferSize, true); 2281 } 2282 2283 static int sceAtracSetAA3DataAndGetID(u32 buffer, u32 bufferSize, u32 fileSize, u32 metadataSizeAddr) { 2284 Atrac *atrac = new Atrac(); 2285 int ret = atrac->AnalyzeAA3(buffer, bufferSize, fileSize); 2286 if (ret < 0) { 2287 // Already logged. 2288 delete atrac; 2289 return ret; 2290 } 2291 int atracID = createAtrac(atrac); 2292 if (atracID < 0) { 2293 delete atrac; 2294 return hleLogError(ME, atracID, "no free ID"); 2295 } 2296 2297 atrac->outputChannels_ = 2; 2298 return _AtracSetData(atracID, buffer, bufferSize, bufferSize, true); 2299 } 2300 2301 int _AtracGetIDByContext(u32 contextAddr) { 2302 int atracID = (int)Memory::Read_U32(contextAddr + 0xfc); 2303 #ifdef USE_FFMPEG 2304 Atrac *atrac = getAtrac(atracID); 2305 if (atrac) 2306 __AtracUpdateOutputMode(atrac, 1); 2307 #endif // USE_FFMPEG 2308 return atracID; 2309 } 2310 2311 void _AtracGenerateContext(Atrac *atrac) { 2312 SceAtracId *context = atrac->context_; 2313 context->info.buffer = atrac->first_.addr; 2314 context->info.bufferByte = atrac->bufferMaxSize_; 2315 context->info.secondBuffer = atrac->second_.addr; 2316 context->info.secondBufferByte = atrac->second_.size; 2317 context->info.codec = atrac->codecType_; 2318 context->info.loopNum = atrac->loopNum_; 2319 context->info.loopStart = atrac->loopStartSample_ > 0 ? atrac->loopStartSample_ : 0; 2320 context->info.loopEnd = atrac->loopEndSample_ > 0 ? atrac->loopEndSample_ : 0; 2321 2322 // Note that we read in the state when loading the atrac object, so it's safe 2323 // to update it back here all the time. Some games, like Sol Trigger, change it. 2324 // TODO: Should we just keep this in PSP ram then, or something? 2325 context->info.state = atrac->bufferState_; 2326 if (atrac->firstSampleOffset_ != 0) { 2327 context->info.samplesPerChan = atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); 2328 } else { 2329 context->info.samplesPerChan = (atrac->codecType_ == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES); 2330 } 2331 context->info.sampleSize = atrac->bytesPerFrame_; 2332 context->info.numChan = atrac->channels_; 2333 context->info.dataOff = atrac->dataOff_; 2334 context->info.endSample = atrac->endSample_ + atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); 2335 context->info.dataEnd = atrac->first_.filesize; 2336 context->info.curOff = atrac->first_.fileoffset; 2337 context->info.decodePos = atrac->DecodePosBySample(atrac->currentSample_); 2338 context->info.streamDataByte = atrac->first_.size - atrac->dataOff_; 2339 2340 u8 *buf = (u8 *)context; 2341 *(u32_le *)(buf + 0xfc) = atrac->atracID_; 2342 2343 NotifyMemInfo(MemBlockFlags::WRITE, atrac->context_.ptr, sizeof(SceAtracId), "AtracContext"); 2344 } 2345 2346 static u32 _sceAtracGetContextAddress(int atracID) { 2347 Atrac *atrac = getAtrac(atracID); 2348 if (!atrac) { 2349 ERROR_LOG(ME, "_sceAtracGetContextAddress(%i): bad atrac id", atracID); 2350 return 0; 2351 } 2352 if (!atrac->context_.IsValid()) { 2353 // allocate a new context_ 2354 u32 contextsize = 256; 2355 atrac->context_ = kernelMemory.Alloc(contextsize, false, "Atrac Context"); 2356 if (atrac->context_.IsValid()) 2357 Memory::Memset(atrac->context_.ptr, 0, 256, "AtracContextClear"); 2358 2359 WARN_LOG(ME, "%08x=_sceAtracGetContextAddress(%i): allocated new context", atrac->context_.ptr, atracID); 2360 } 2361 else 2362 WARN_LOG(ME, "%08x=_sceAtracGetContextAddress(%i)", atrac->context_.ptr, atracID); 2363 if (atrac->context_.IsValid()) 2364 _AtracGenerateContext(atrac); 2365 return atrac->context_.ptr; 2366 } 2367 2368 struct At3HeaderMap { 2369 u16 bytes; 2370 u16 channels; 2371 u8 jointStereo; 2372 2373 bool Matches(const Atrac *at) const { 2374 return bytes == at->bytesPerFrame_ && channels == at->channels_; 2375 } 2376 }; 2377 2378 // These should represent all possible supported bitrates (66, 104, and 132 for stereo.) 2379 static const At3HeaderMap at3HeaderMap[] = { 2380 { 0x00C0, 1, 0 }, // 132/2 (66) kbps mono 2381 { 0x0098, 1, 0 }, // 105/2 (52.5) kbps mono 2382 { 0x0180, 2, 0 }, // 132 kbps stereo 2383 { 0x0130, 2, 0 }, // 105 kbps stereo 2384 // At this size, stereo can only use joint stereo. 2385 { 0x00C0, 2, 1 }, // 66 kbps stereo 2386 }; 2387 2388 static bool initAT3Decoder(Atrac *atrac) { 2389 atrac->bitrate_ = (atrac->bytesPerFrame_ * 352800) / 1000; 2390 atrac->bitrate_ = (atrac->bitrate_ + 511) >> 10; 2391 atrac->jointStereo_ = false; 2392 2393 // See if we can match the actual jointStereo value. 2394 for (size_t i = 0; i < ARRAY_SIZE(at3HeaderMap); ++i) { 2395 if (at3HeaderMap[i].Matches(atrac)) { 2396 atrac->jointStereo_ = at3HeaderMap[i].jointStereo; 2397 return true; 2398 } 2399 } 2400 return false; 2401 } 2402 2403 static void initAT3plusDecoder(Atrac *atrac) { 2404 atrac->bitrate_ = (atrac->bytesPerFrame_ * 352800) / 1000; 2405 atrac->bitrate_ = ((atrac->bitrate_ >> 11) + 8) & 0xFFFFFFF0; 2406 atrac->jointStereo_ = false; 2407 } 2408 2409 static int sceAtracLowLevelInitDecoder(int atracID, u32 paramsAddr) { 2410 Atrac *atrac = getAtrac(atracID); 2411 if (!atrac) { 2412 return hleLogError(ME, ATRAC_ERROR_BAD_ATRACID, "bad atrac ID"); 2413 } 2414 2415 if (atrac->codecType_ != PSP_MODE_AT_3 && atrac->codecType_ != PSP_MODE_AT_3_PLUS) { 2416 // TODO: Error code? Was silently 0 before, and just didn't work. Shouldn't ever happen... 2417 return hleReportError(ME, ATRAC_ERROR_UNKNOWN_FORMAT, "bad codec type"); 2418 } 2419 2420 if (!Memory::IsValidAddress(paramsAddr)) { 2421 // TODO: Returning zero as code was before. Needs testing. 2422 return hleReportError(ME, 0, "invalid pointers"); 2423 } 2424 2425 atrac->channels_ = Memory::Read_U32(paramsAddr); 2426 atrac->outputChannels_ = Memory::Read_U32(paramsAddr + 4); 2427 atrac->bufferMaxSize_ = Memory::Read_U32(paramsAddr + 8); 2428 atrac->bytesPerFrame_ = atrac->bufferMaxSize_; 2429 atrac->first_.writableBytes = atrac->bytesPerFrame_; 2430 atrac->ResetData(); 2431 2432 const char *codecName = atrac->codecType_ == PSP_MODE_AT_3 ? "atrac3" : "atrac3+"; 2433 const char *channelName = atrac->channels_ == 1 ? "mono" : "stereo"; 2434 2435 if (atrac->codecType_ == PSP_MODE_AT_3) { 2436 if (!initAT3Decoder(atrac)) { 2437 ERROR_LOG_REPORT(ME, "AT3 header map lacks entry for bpf: %i channels: %i", atrac->bytesPerFrame_, atrac->channels_); 2438 // TODO: Should we return an error code for these values? 2439 } 2440 } else if (atrac->codecType_ == PSP_MODE_AT_3_PLUS) { 2441 initAT3plusDecoder(atrac); 2442 } 2443 2444 atrac->dataOff_ = 0; 2445 atrac->first_.size = 0; 2446 atrac->first_.filesize = atrac->bytesPerFrame_; 2447 atrac->bufferState_ = ATRAC_STATUS_LOW_LEVEL; 2448 atrac->dataBuf_ = new u8[atrac->first_.filesize]; 2449 atrac->currentSample_ = 0; 2450 int ret = __AtracSetContext(atrac); 2451 2452 if (atrac->context_.IsValid()) { 2453 _AtracGenerateContext(atrac); 2454 } 2455 2456 if (ret < 0) { 2457 // Already logged. 2458 return ret; 2459 } 2460 return hleLogSuccessInfoI(ME, ret, "%s %s audio", codecName, channelName); 2461 } 2462 2463 static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesConsumedAddr, u32 samplesAddr, u32 sampleBytesAddr) { 2464 auto srcp = PSPPointer<u8>::Create(sourceAddr); 2465 auto srcConsumed = PSPPointer<u32_le>::Create(sourceBytesConsumedAddr); 2466 auto outp = PSPPointer<u8>::Create(samplesAddr); 2467 auto outWritten = PSPPointer<u32_le>::Create(sampleBytesAddr); 2468 2469 Atrac *atrac = getAtrac(atracID); 2470 if (!atrac) { 2471 return hleLogError(ME, ATRAC_ERROR_BAD_ATRACID, "bad atrac ID"); 2472 } 2473 2474 if (!srcp.IsValid() || !srcConsumed.IsValid() || !outp.IsValid() || !outWritten.IsValid()) { 2475 // TODO: Returning zero as code was before. Needs testing. 2476 return hleReportError(ME, 0, "invalid pointers"); 2477 } 2478 2479 int numSamples = (atrac->codecType_ == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES); 2480 2481 if (!atrac->failedDecode_) { 2482 atrac->FillLowLevelPacket(srcp); 2483 2484 AtracDecodeResult res = atrac->DecodePacket(); 2485 if (res == ATDECODE_GOTFRAME) { 2486 #ifdef USE_FFMPEG 2487 // got a frame 2488 numSamples = atrac->frame_->nb_samples; 2489 2490 u8 *out = outp; 2491 int avret = swr_convert(atrac->swrCtx_, &out, numSamples, 2492 (const u8**)atrac->frame_->extended_data, numSamples); 2493 u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16); 2494 NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outBytes, "AtracLowLevelDecode"); 2495 if (avret < 0) { 2496 ERROR_LOG(ME, "swr_convert: Error while converting %d", avret); 2497 } 2498 #endif // USE_FFMPEG 2499 } else { 2500 // TODO: Error code otherwise? 2501 } 2502 } 2503 2504 *outWritten = numSamples * atrac->outputChannels_ * sizeof(s16); 2505 *srcConsumed = atrac->bytesPerFrame_; 2506 2507 return hleLogDebug(ME, hleDelayResult(0, "low level atrac decode data", atracDecodeDelay)); 2508 } 2509 2510 static int sceAtracSetAA3HalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 bufferSize, u32 fileSize) { 2511 if (readSize > bufferSize) { 2512 return hleLogError(ME, ATRAC_ERROR_INCORRECT_READ_SIZE, "read size too large"); 2513 } 2514 2515 Atrac *atrac = new Atrac(); 2516 int ret = atrac->AnalyzeAA3(buffer, readSize, fileSize); 2517 if (ret < 0) { 2518 // Already logged. 2519 delete atrac; 2520 return ret; 2521 } 2522 int atracID = createAtrac(atrac); 2523 if (atracID < 0) { 2524 delete atrac; 2525 return hleLogError(ME, atracID, "no free ID"); 2526 } 2527 2528 atrac->outputChannels_ = 2; 2529 return _AtracSetData(atracID, buffer, readSize, bufferSize, true); 2530 } 2531 2532 const HLEFunction sceAtrac3plus[] = { 2533 {0X7DB31251, &WrapU_IU<sceAtracAddStreamData>, "sceAtracAddStreamData", 'x', "ix" }, 2534 {0X6A8C3CD5, &WrapU_IUUUU<sceAtracDecodeData>, "sceAtracDecodeData", 'x', "ixppp"}, 2535 {0XD5C28CC0, &WrapU_V<sceAtracEndEntry>, "sceAtracEndEntry", 'x', "" }, 2536 {0X780F88D1, &WrapU_I<sceAtracGetAtracID>, "sceAtracGetAtracID", 'i', "x" }, 2537 {0XCA3CA3D2, &WrapU_IIU<sceAtracGetBufferInfoForResetting>, "sceAtracGetBufferInfoForReseting", 'x', "iix" }, 2538 {0XA554A158, &WrapU_IU<sceAtracGetBitrate>, "sceAtracGetBitrate", 'x', "ip" }, 2539 {0X31668BAA, &WrapU_IU<sceAtracGetChannel>, "sceAtracGetChannel", 'x', "ip" }, 2540 {0XFAA4F89B, &WrapU_IUU<sceAtracGetLoopStatus>, "sceAtracGetLoopStatus", 'x', "ipp" }, 2541 {0XE88F759B, &WrapU_IU<sceAtracGetInternalErrorInfo>, "sceAtracGetInternalErrorInfo", 'x', "ip" }, 2542 {0XD6A5F2F7, &WrapU_IU<sceAtracGetMaxSample>, "sceAtracGetMaxSample", 'x', "ip" }, 2543 {0XE23E3A35, &WrapU_IU<sceAtracGetNextDecodePosition>, "sceAtracGetNextDecodePosition", 'x', "ip" }, 2544 {0X36FAABFB, &WrapU_IU<sceAtracGetNextSample>, "sceAtracGetNextSample", 'x', "ip" }, 2545 {0X9AE849A7, &WrapU_IU<sceAtracGetRemainFrame>, "sceAtracGetRemainFrame", 'x', "ip" }, 2546 {0X83E85EA0, &WrapU_IUU<sceAtracGetSecondBufferInfo>, "sceAtracGetSecondBufferInfo", 'x', "ipp" }, 2547 {0XA2BBA8BE, &WrapU_IUUU<sceAtracGetSoundSample>, "sceAtracGetSoundSample", 'x', "ippp" }, 2548 {0X5D268707, &WrapU_IUUU<sceAtracGetStreamDataInfo>, "sceAtracGetStreamDataInfo", 'x', "ippp" }, 2549 {0X61EB33F5, &WrapU_I<sceAtracReleaseAtracID>, "sceAtracReleaseAtracID", 'x', "i" }, 2550 {0X644E5607, &WrapU_IIII<sceAtracResetPlayPosition>, "sceAtracResetPlayPosition", 'x', "iiii" }, 2551 {0X3F6E26B5, &WrapU_IUUU<sceAtracSetHalfwayBuffer>, "sceAtracSetHalfwayBuffer", 'x', "ixxx" }, 2552 {0X83BF7AFD, &WrapU_IUU<sceAtracSetSecondBuffer>, "sceAtracSetSecondBuffer", 'x', "ixx" }, 2553 {0X0E2A73AB, &WrapU_IUU<sceAtracSetData>, "sceAtracSetData", 'x', "ixx" }, 2554 {0X7A20E7AF, &WrapI_UI<sceAtracSetDataAndGetID>, "sceAtracSetDataAndGetID", 'i', "xx" }, 2555 {0XD1F59FDB, &WrapU_V<sceAtracStartEntry>, "sceAtracStartEntry", 'x', "" }, 2556 {0X868120B5, &WrapU_II<sceAtracSetLoopNum>, "sceAtracSetLoopNum", 'x', "ii" }, 2557 {0X132F1ECA, &WrapI_II<sceAtracReinit>, "sceAtracReinit", 'x', "ii" }, 2558 {0XECA32A99, &WrapI_I<sceAtracIsSecondBufferNeeded>, "sceAtracIsSecondBufferNeeded", 'i', "i" }, 2559 {0X0FAE370E, &WrapI_UUU<sceAtracSetHalfwayBufferAndGetID>, "sceAtracSetHalfwayBufferAndGetID", 'i', "xxx" }, 2560 {0X2DD3E298, &WrapU_IIU<sceAtracGetBufferInfoForResetting>, "sceAtracGetBufferInfoForResetting", 'x', "iix" }, 2561 {0X5CF9D852, &WrapI_IUUU<sceAtracSetMOutHalfwayBuffer>, "sceAtracSetMOutHalfwayBuffer", 'x', "ixxx" }, 2562 {0XF6837A1A, &WrapU_IUU<sceAtracSetMOutData>, "sceAtracSetMOutData", 'x', "ixx" }, 2563 {0X472E3825, &WrapI_UU<sceAtracSetMOutDataAndGetID>, "sceAtracSetMOutDataAndGetID", 'i', "xx" }, 2564 {0X9CD7DE03, &WrapI_UUU<sceAtracSetMOutHalfwayBufferAndGetID>, "sceAtracSetMOutHalfwayBufferAndGetID", 'i', "xxx" }, 2565 {0XB3B5D042, &WrapI_IU<sceAtracGetOutputChannel>, "sceAtracGetOutputChannel", 'x', "ip" }, 2566 {0X5622B7C1, &WrapI_UUUU<sceAtracSetAA3DataAndGetID>, "sceAtracSetAA3DataAndGetID", 'i', "xxxp" }, 2567 {0X5DD66588, &WrapI_UUUU<sceAtracSetAA3HalfwayBufferAndGetID>, "sceAtracSetAA3HalfwayBufferAndGetID", 'i', "xxxx" }, 2568 {0X231FC6B7, &WrapU_I<_sceAtracGetContextAddress>, "_sceAtracGetContextAddress", 'x', "i" }, 2569 {0X1575D64B, &WrapI_IU<sceAtracLowLevelInitDecoder>, "sceAtracLowLevelInitDecoder", 'x', "ix" }, 2570 {0X0C116E1B, &WrapI_IUUUU<sceAtracLowLevelDecode>, "sceAtracLowLevelDecode", 'x', "ixpxp"}, 2571 }; 2572 2573 void Register_sceAtrac3plus() { 2574 // Two names 2575 RegisterModule("sceATRAC3plus_Library", ARRAY_SIZE(sceAtrac3plus), sceAtrac3plus); 2576 RegisterModule("sceAtrac3plus", ARRAY_SIZE(sceAtrac3plus), sceAtrac3plus); 2577 } 2578