1 // Copyright (c) 2013- 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 #pragma once
19 
20 #include <cmath>
21 
22 #include "Core/HW/MediaEngine.h"
23 #include "Core/HLE/sceAudio.h"
24 
25 struct AVFrame;
26 struct AVCodec;
27 struct AVCodecContext;
28 struct SwrContext;
29 
30 // Wraps FFMPEG for audio decoding in a nice interface.
31 // Decodes packet by packet - does NOT demux.
32 
33 // Based on http://ffmpeg.org/doxygen/trunk/doc_2examples_2decoding_encoding_8c-example.html#_a13
34 
35 // audioType
36 enum {
37 	PSP_CODEC_AT3PLUS = 0x00001000,
38 	PSP_CODEC_AT3 = 0x00001001,
39 	PSP_CODEC_MP3 = 0x00001002,
40 	PSP_CODEC_AAC = 0x00001003,
41 };
42 
43 class SimpleAudio {
44 public:
45 	SimpleAudio(int audioType, int sample_rate = 44100, int channels = 2);
46 	~SimpleAudio();
47 
48 	bool Decode(void* inbuf, int inbytes, uint8_t *outbuf, int *outbytes);
49 	bool IsOK() const;
50 
51 	int GetOutSamples();
52 	int GetSourcePos();
53 	int GetAudioCodecID(int audioType); // Get audioCodecId from audioType
54 
55 	// Not save stated, only used by UI.  Used for ATRAC3 (non+) files.
56 	void SetExtraData(u8 *data, int size, int wav_bytes_per_packet);
57 
58 	void SetChannels(int channels);
59 
60 	// These two are only here because of save states.
GetAudioType()61 	int GetAudioType() const { return audioType; }
SetResampleFrequency(int freq)62 	void SetResampleFrequency(int freq) { wanted_resample_freq = freq; }
63 
64 	// Just metadata.
SetCtxPtr(u32 ptr)65 	void SetCtxPtr(u32 ptr) { ctxPtr = ptr;  }
GetCtxPtr()66 	u32 GetCtxPtr() const { return ctxPtr; }
67 
68 private:
69 	void Init();
70 	bool OpenCodec(int block_align);
71 
72 	u32 ctxPtr;
73 	int audioType;
74 	int sample_rate_;
75 	int channels_;
76 	int outSamples; // output samples per frame
77 	int srcPos; // bytes consumed in source during the last decoding
78 	int wanted_resample_freq; // wanted resampling rate/frequency
79 
80 	AVFrame *frame_;
81 	AVCodec *codec_;
82 	AVCodecContext  *codecCtx_;
83 	SwrContext      *swrCtx_;
84 
85 	bool codecOpen_;
86 };
87 
88 void AudioClose(SimpleAudio **ctx);
89 const char *GetCodecName(int codec);  // audioType
90 bool IsValidCodec(int codec);
91 
92 class AuCtx {
93 public:
94 	AuCtx();
95 	~AuCtx();
96 
97 	u32 AuDecode(u32 pcmAddr);
98 
99 	u32 AuNotifyAddStreamData(int size);
100 	int AuCheckStreamDataNeeded();
101 	int AuStreamBytesNeeded();
102 	int AuStreamWorkareaSize();
103 	u32 AuResetPlayPosition();
104 	u32 AuResetPlayPositionByFrame(int position);
105 
106 	u32 AuSetLoopNum(int loop);
107 	u32 AuGetLoopNum();
108 
109 	u32 AuGetInfoToAddStreamData(u32 bufPtr, u32 sizePtr, u32 srcPosPtr);
AuGetMaxOutputSample()110 	u32 AuGetMaxOutputSample() const { return MaxOutputSample; }
AuGetSumDecodedSample()111 	u32 AuGetSumDecodedSample() const { return SumDecodedSamples; }
AuGetChannelNum()112 	int AuGetChannelNum() const { return Channels; }
AuGetBitRate()113 	int AuGetBitRate() const { return BitRate; }
AuGetSamplingRate()114 	int AuGetSamplingRate() const { return SamplingRate; }
AuGetVersion()115 	int AuGetVersion() const { return Version; }
AuGetFrameNum()116 	int AuGetFrameNum() const { return FrameNum; }
117 
118 	void DoState(PointerWrap &p);
119 
EatSourceBuff(int amount)120 	void EatSourceBuff(int amount) {
121 		if (amount > (int)sourcebuff.size()) {
122 			amount = (int)sourcebuff.size();
123 		}
124 		if (amount > 0)
125 			sourcebuff.erase(sourcebuff.begin(), sourcebuff.begin() + amount);
126 		AuBufAvailable -= amount;
127 	}
128 	// Au source information. Written to from for example sceAacInit so public for now.
129 	u64 startPos;
130 	u64 endPos;
131 	u32 AuBuf;
132 	u32 AuBufSize;
133 	u32 PCMBuf;
134 	u32 PCMBufSize;
135 	int freq = -1;
136 	int BitRate = 0;
137 	int SamplingRate = -1;
138 	int Channels = 0;
139 	int Version = -1;
140 
141 	// State variables. These should be relatively easy to move into private.
142 	u32 SumDecodedSamples;
143 	int LoopNum;
144 	u32 MaxOutputSample = 0;
145 	int FrameNum; // number of decoded frame
146 
147 	// Au decoder
148 	SimpleAudio *decoder;
149 
150 	// Au type
151 	int audioType;
152 
153 	// buffers informations
154 	int AuBufAvailable; // the available buffer of AuBuf to be able to recharge data
155 	int readPos; // read position in audio source file
156 	int askedReadSize; // the size of data requied to be read from file by the game
157 
158 private:
159 	size_t FindNextMp3Sync();
160 
161 	std::vector<u8> sourcebuff; // source buffer
162 };
163 
164 
165 
166 
167