Ticket #9282: 9282.diff
| File 9282.diff, 18.9 KB (added by , 15 years ago) |
|---|
-
mythtv/libs/libmyth/audiooutputbase.h
Property changes on: . ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r27358,27368-27369
95 95 virtual void bufferOutputData(bool y){ buffer_output_data_for_use = y; } 96 96 virtual int readOutputData(unsigned char *read_buffer, int max_length); 97 97 98 static const uint kAudioSRCInputSize = 16384<<1;99 static const uint kAudioSRCOutputSize = 16384<<3; 98 static const uint kAudioSRCInputSize = 32768; 99 100 100 /// Audio Buffer Size -- should be divisible by 32,24,16,12,10,8,6,4,2.. 101 101 static const uint kAudioRingBufferSize = 3072000; 102 102 … … 224 224 uint memory_corruption_test0; 225 225 float src_in_buf[kAudioSRCInputSize + 16]; 226 226 uint memory_corruption_test1; 227 float src_out[kAudioSRCOutputSize]; 227 float *src_out; 228 int kAudioSRCOutputSize; 228 229 uint memory_corruption_test2; 229 230 /** main audio buffer */ 230 231 uchar audiobuffer[kAudioRingBufferSize]; -
mythtv/libs/libmyth/audiooutputbase.cpp
93 93 94 94 memory_corruption_test0(0xdeadbeef), 95 95 memory_corruption_test1(0xdeadbeef), 96 src_out(NULL), kAudioSRCOutputSize(0), 96 97 memory_corruption_test2(0xdeadbeef), 97 98 memory_corruption_test3(0xdeadbeef) 98 99 { … … 100 101 // The following are not bzero() because MS Windows doesn't like it. 101 102 memset(&src_data, 0, sizeof(SRC_DATA)); 102 103 memset(src_in, 0, sizeof(float) * kAudioSRCInputSize); 103 memset(src_out, 0, sizeof(float) * kAudioSRCOutputSize);104 104 memset(audiobuffer, 0, sizeof(char) * kAudioRingBufferSize); 105 105 106 106 // Default SRC quality - QUALITY_HIGH is quite expensive … … 134 134 delete output_settings; 135 135 delete output_settingsraw; 136 136 137 if (kAudioSRCOutputSize > 0) 138 delete[] src_out; 139 137 140 assert(memory_corruption_test0 == 0xdeadbeef); 138 141 assert(memory_corruption_test1 == 0xdeadbeef); 139 142 assert(memory_corruption_test2 == 0xdeadbeef); … … 474 477 475 478 src_data.src_ratio = (double)samplerate / settings.samplerate; 476 479 src_data.data_in = src_in; 480 int newsize = ((long)((float)kAudioSRCInputSize * 481 samplerate / settings.samplerate) + 482 15) & ~0xf; 483 if (kAudioSRCOutputSize < newsize) 484 { 485 kAudioSRCOutputSize = newsize; 486 VBAUDIO(QString("Resampler allocating %1").arg(newsize)); 487 if (src_out) 488 delete[] src_out; 489 src_out = new float[kAudioSRCOutputSize]; 490 } 477 491 src_data.data_out = src_out; 478 492 src_data.output_frames = kAudioSRCOutputSize; 479 493 src_data.end_of_input = 0; … … 789 803 790 804 /* timecode is the stretch adjusted version 791 805 of major post-stretched buffer contents 792 processing latencies are catered for in Add Samples/SetAudiotime806 processing latencies are catered for in AddFrames/SetAudiotime 793 807 to eliminate race */ 794 808 audiotime = audbuf_timecode - ( 795 809 ((main_buffer + soundcard_buffer) * eff_stretchfactor ) / … … 819 833 /** 820 834 * Set the timecode of the top of the ringbuffer 821 835 * Exclude all other processing elements as they dont vary 822 * between Add Samples calls836 * between AddFrames calls 823 837 */ 824 838 void AudioOutputBase::SetAudiotime(int frames, int64_t timecode) 825 839 { … … 841 855 842 856 int64_t old_audbuf_timecode = audbuf_timecode; 843 857 844 audbuf_timecode = timecode + 858 audbuf_timecode = timecode + 845 859 (((frames + processframes_unstretched) * 100000) + 846 860 (processframes_stretched * eff_stretchfactor )) / effdsp; 847 861 848 862 // check for timecode wrap and reset audiotime if detected 849 // timecode will always be monotonic asc if not seeked and reset 863 // timecode will always be monotonic asc if not seeked and reset 850 864 // happens if seek or pause happens 851 865 if (audbuf_timecode < old_audbuf_timecode) 852 866 audiotime = 0; … … 979 993 } 980 994 981 995 // Upmix to 6ch via FreeSurround 982 983 996 // Calculate frame size of input 984 997 off = processing ? 4 : output_settings->SampleSize(format); 985 998 off *= source_channels; 986 999 987 int i = 0; 988 while (i < frames) 989 i += upmixer->putFrames(buffer + i * off, frames - i, source_channels); 1000 int remaining_frames = frames; 1001 len = 0; 1002 do 1003 { 1004 int i; 1005 frames = remaining_frames; 1006 if (frames * source_channels > SURROUND_BUFSIZE) 1007 { 1008 frames = SURROUND_BUFSIZE / source_channels; 1009 } 990 1010 991 int nFrames = upmixer->numFrames(); 992 if (!nFrames) 993 return 0; 1011 i = 0; 1012 while (i < frames) 1013 i += upmixer->putFrames(buffer + i * off, 1014 frames - i, source_channels); 994 1015 995 len = CheckFreeSpace(nFrames); 1016 remaining_frames -= i; 1017 buffer += i * off; 996 1018 997 int bdFrames = bdiff / bpf; 998 if (bdFrames < nFrames) 999 { 1000 upmixer->receiveFrames((float *)(WPOS), bdFrames); 1001 nFrames -= bdFrames; 1002 org_waud = 0; 1019 int nFrames = upmixer->numFrames(); 1020 if (!nFrames) 1021 continue; 1022 1023 len += CheckFreeSpace(nFrames); 1024 1025 int bdFrames = (kAudioRingBufferSize - org_waud) / bpf; 1026 if (bdFrames < nFrames) 1027 { 1028 upmixer->receiveFrames((float *)(WPOS), bdFrames); 1029 nFrames -= bdFrames; 1030 org_waud = 0; 1031 } 1032 if (nFrames > 0) 1033 upmixer->receiveFrames((float *)(WPOS), nFrames); 1034 1035 org_waud += nFrames * bpf; 1003 1036 } 1004 if (nFrames > 0) 1005 upmixer->receiveFrames((float *)(WPOS), nFrames); 1006 1007 org_waud += nFrames * bpf; 1037 while (remaining_frames > 0); 1008 1038 return len; 1009 1039 } 1010 1040 … … 1013 1043 * 1014 1044 * Returns false if there's not enough space right now 1015 1045 */ 1016 bool AudioOutputBase::AddFrames(void *buffer, int in_frames, int64_t timecode) 1046 bool AudioOutputBase::AddFrames(void *in_buffer, int in_frames, 1047 int64_t timecode) 1017 1048 { 1018 1049 int org_waud = waud, afree = audiofree(); 1019 1050 int frames = in_frames; 1020 int bpf = bytes_per_frame, len = frames * source_bytes_per_frame; 1051 void *buffer = in_buffer; 1052 int bpf = bytes_per_frame, len = frames * source_bytes_per_frame; 1021 1053 int used = kAudioRingBufferSize - afree; 1022 1054 bool music = false; 1023 1055 int bdiff; … … 1044 1076 // Send original samples to mythmusic visualisation 1045 1077 timecode = (int64_t)(frames_buffered) * 1000 / source_samplerate; 1046 1078 frames_buffered += frames; 1047 dispatchVisual((uchar *) buffer, len, timecode, source_channels,1079 dispatchVisual((uchar *)in_buffer, len, timecode, source_channels, 1048 1080 output_settings->FormatToBits(format)); 1049 1081 music = true; 1050 1082 } 1051 1083 1084 // Calculate amount of free space required in ringbuffer 1052 1085 if (processing) 1053 1086 { 1054 // Convert to floats 1055 len = AudioOutputUtil::toFloat(format, src_in, buffer, len); 1087 // Final float conversion space requirement 1088 len = sizeof(*src_in_buf) / 1089 AudioOutputSettings::SampleSize(format) * len; 1056 1090 1057 1091 // Account for changes in number of channels 1058 1092 if (needs_upmix || needs_downmix) … … 1074 1108 1075 1109 if (len > afree) 1076 1110 { 1077 VBAUDIOTS("Buffer is full, AddFrames returning false");1078 return false; // would overflow1111 VBAUDIOTS("Buffer is full, AddFrames returning false"); 1112 return false; // would overflow 1079 1113 } 1080 1114 1081 // Perform downmix if necessary 1082 if (needs_downmix) 1083 if(AudioOutputDownmix::DownmixFrames(source_channels, channels, 1084 src_in, src_in, frames) < 0) 1085 VBERROR("Error occurred while downmixing"); 1115 int frames_remaining = in_frames; 1116 int frames_offset = 0; 1117 int frames_final = 0; 1086 1118 1087 // Resample if necessary 1088 if (need_resampler && src_ctx) 1119 while(frames_remaining > 0) 1089 1120 { 1090 src_data.input_frames = frames;1091 int error = src_process(src_ctx, &src_data);1121 buffer = (char *)in_buffer + frames_offset; 1122 frames = frames_remaining; 1092 1123 1093 if (error) 1094 VBERROR(QString("Error occurred while resampling audio: %1") 1095 .arg(src_strerror(error))); 1124 len = frames * source_bytes_per_frame; 1096 1125 1097 buffer = src_out; 1098 in_frames = frames = src_data.output_frames_gen; 1099 } 1100 else if (processing) 1101 buffer = src_in; 1126 if (processing) 1127 { 1128 if (frames * source_channels > (int)kAudioSRCInputSize) 1129 { 1130 frames = kAudioSRCInputSize / source_channels; 1131 len = frames * source_bytes_per_frame; 1132 frames_offset += len; 1133 } 1134 // Convert to floats 1135 len = AudioOutputUtil::toFloat(format, src_in, buffer, len); 1136 } 1137 frames_remaining -= frames; 1102 1138 1103 /* we want the timecode of the last sample added but we are given the 1104 timecode of the first - add the time in ms that the frames added 1105 represent */ 1139 // Perform downmix if necessary 1140 if (needs_downmix) 1141 if(AudioOutputDownmix::DownmixFrames(source_channels, channels, 1142 src_in, src_in, frames) < 0) 1143 VBERROR("Error occurred while downmixing"); 1106 1144 1107 // Copy samples into audiobuffer, with upmix if necessary 1108 if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0) 1109 { 1110 SetAudiotime(in_frames, timecode); 1111 return true; 1112 } 1145 // Resample if necessary 1146 if (need_resampler && src_ctx) 1147 { 1148 src_data.input_frames = frames; 1149 int error = src_process(src_ctx, &src_data); 1113 1150 1114 frames = len / bpf; 1151 if (error) 1152 VBERROR(QString("Error occurred while resampling audio: %1") 1153 .arg(src_strerror(error))); 1115 1154 1116 bdiff = kAudioRingBufferSize - waud; 1155 buffer = src_out; 1156 frames = src_data.output_frames_gen; 1157 frames_final += frames; 1158 } 1159 else 1160 { 1161 frames_final += frames; 1162 if (processing) 1163 buffer = src_in; 1164 } 1117 1165 1118 if (pSoundStretch) 1119 { 1120 // does not change the timecode, only the number of samples 1121 org_waud = waud; 1122 int bdFrames = bdiff / bpf; 1166 /* we want the timecode of the last sample added but we are given the 1167 timecode of the first - add the time in ms that the frames added 1168 represent */ 1123 1169 1124 if (bdiff < len) 1170 // Copy samples into audiobuffer, with upmix if necessary 1171 if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0) 1125 1172 { 1126 pSoundStretch->putSamples((STST *)(WPOS), bdFrames); 1127 pSoundStretch->putSamples((STST *)ABUF, (len - bdiff) / bpf); 1173 continue; 1128 1174 } 1129 else1130 pSoundStretch->putSamples((STST *)(WPOS), frames);1131 1175 1132 int nFrames = pSoundStretch->numSamples(); 1133 if (nFrames > frames) 1134 CheckFreeSpace(nFrames); 1176 frames = len / bpf; 1135 1177 1136 len = nFrames * bpf;1178 bdiff = kAudioRingBufferSize - waud; 1137 1179 1138 if ( nFrames > bdFrames)1180 if (pSoundStretch) 1139 1181 { 1140 nFrames -= pSoundStretch->receiveSamples((STST *)(WPOS), bdFrames); 1141 org_waud = 0; 1142 } 1143 if (nFrames > 0) 1144 nFrames = pSoundStretch->receiveSamples((STST *)(WPOS), nFrames); 1182 // does not change the timecode, only the number of samples 1183 org_waud = waud; 1184 int bdFrames = bdiff / bpf; 1145 1185 1146 org_waud += nFrames * bpf; 1147 } 1186 if (bdiff < len) 1187 { 1188 pSoundStretch->putSamples((STST *)(WPOS), bdFrames); 1189 pSoundStretch->putSamples((STST *)ABUF, (len - bdiff) / bpf); 1190 } 1191 else 1192 pSoundStretch->putSamples((STST *)(WPOS), frames); 1148 1193 1149 if (internal_vol && SWVolume()) 1150 { 1151 org_waud = waud; 1152 int num = len; 1194 int nFrames = pSoundStretch->numSamples(); 1195 if (nFrames > frames) 1196 CheckFreeSpace(nFrames); 1153 1197 1154 if (bdiff <= num) 1155 { 1156 AudioOutputUtil::AdjustVolume(WPOS, bdiff, volume, 1157 music, needs_upmix && upmixer); 1158 num -= bdiff; 1159 org_waud = 0; 1198 len = nFrames * bpf; 1199 1200 if (nFrames > bdFrames) 1201 { 1202 nFrames -= pSoundStretch->receiveSamples((STST *)(WPOS), 1203 bdFrames); 1204 org_waud = 0; 1205 } 1206 if (nFrames > 0) 1207 nFrames = pSoundStretch->receiveSamples((STST *)(WPOS), 1208 nFrames); 1209 1210 org_waud += nFrames * bpf; 1160 1211 } 1161 if (num > 0)1162 AudioOutputUtil::AdjustVolume(WPOS, num, volume,1163 music, needs_upmix && upmixer);1164 org_waud += num;1165 }1166 1212 1167 if (encoder)1168 {1169 org_waud= waud;1170 int to_get = 0;1213 if (internal_vol && SWVolume()) 1214 { 1215 org_waud = waud; 1216 int num = len; 1171 1217 1172 if (bdiff < len) 1173 { 1174 encoder->Encode(WPOS, bdiff, processing); 1175 to_get = encoder->Encode(ABUF, len - bdiff, processing); 1218 if (bdiff <= num) 1219 { 1220 AudioOutputUtil::AdjustVolume(WPOS, bdiff, volume, 1221 music, needs_upmix && upmixer); 1222 num -= bdiff; 1223 org_waud = 0; 1224 } 1225 if (num > 0) 1226 AudioOutputUtil::AdjustVolume(WPOS, num, volume, 1227 music, needs_upmix && upmixer); 1228 org_waud += num; 1176 1229 } 1177 else1178 to_get = encoder->Encode(WPOS, len, processing);1179 1230 1180 if ( bdiff <= to_get)1231 if (encoder) 1181 1232 { 1182 encoder->GetFrames(WPOS, bdiff); 1183 to_get -= bdiff; 1184 org_waud = 0; 1233 org_waud = waud; 1234 int org_waud2 = waud; 1235 int remaining = len; 1236 int to_get = 0; 1237 // The AC3 encoder can only work on 128kB of data at a time 1238 int maxframes = (INBUFSIZE / encoder->FrameSize()) * 1239 encoder->FrameSize(); 1240 1241 do 1242 { 1243 len = remaining; 1244 if (len > maxframes) 1245 { 1246 len = maxframes; 1247 } 1248 remaining -= len; 1249 1250 bdiff = kAudioRingBufferSize - org_waud; 1251 if (bdiff < len) 1252 { 1253 encoder->Encode(WPOS, bdiff, processing); 1254 to_get = encoder->Encode(ABUF, len - bdiff, processing); 1255 org_waud = len - bdiff; 1256 } 1257 else 1258 { 1259 to_get = encoder->Encode(WPOS, len, processing); 1260 org_waud += len; 1261 } 1262 1263 bdiff = kAudioRingBufferSize - org_waud2; 1264 if (bdiff <= to_get) 1265 { 1266 encoder->GetFrames(audiobuffer + org_waud2, bdiff); 1267 to_get -= bdiff ; 1268 org_waud2 = 0; 1269 } 1270 if (to_get > 0) 1271 encoder->GetFrames(audiobuffer + org_waud2, to_get); 1272 1273 org_waud2 += to_get; 1274 } 1275 while (remaining > 0); 1276 org_waud = org_waud2; 1185 1277 } 1186 if (to_get > 0)1187 encoder->GetFrames(WPOS, to_get);1188 1278 1189 org_waud += to_get;1279 waud = org_waud; 1190 1280 } 1191 1281 1192 waud = org_waud;1282 SetAudiotime(frames_final, timecode); 1193 1283 1194 SetAudiotime(in_frames, timecode);1195 1196 1284 return true; 1197 1285 } 1198 1286 -
mythtv/libs/libmyth/audiooutpututil.cpp
120 120 } 121 121 122 122 /* 123 All fromFloat variants require 16 byte aligned output buffers on x86 124 The SSE code processes 16 bytes at a time and leaves any remainder for the C 125 - there is no remainder in practice */ 123 The SSE code processes 16 bytes at a time and leaves any remainder for the C 124 - there is no remainder in practice */ 126 125 127 126 static int fromFloat8(uchar *out, float *in, int len) 128 127 { … … 130 129 float f = (1<<7) - 1; 131 130 132 131 #if ARCH_X86 133 if (sse_check() && len >= 16 )132 if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0) 134 133 { 135 134 int loops = len >> 4; 136 135 i = loops << 4; … … 235 234 float f = (1<<15) - 1; 236 235 237 236 #if ARCH_X86 238 if (sse_check() && len >= 16 )237 if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0) 239 238 { 240 239 int loops = len >> 4; 241 240 i = loops << 4; … … 342 341 shift = 0; 343 342 344 343 #if ARCH_X86 345 if (sse_check() && len >= 16 )344 if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0) 346 345 { 347 346 float o = 1, mo = -1; 348 347 int loops = len >> 4; … … 407 406 int i = 0; 408 407 409 408 #if ARCH_X86 410 if (sse_check() && len >= 16 )409 if (sse_check() && len >= 16 && ((unsigned long)in & 0xf) == 0) 411 410 { 412 411 int loops = len >> 4; 413 412 float o = 1, mo = -1; -
mythtv/libs/libmythfreesurround/freesurround.cpp
37 37 #include <QDateTime> 38 38 39 39 // our default internal block size, in floats 40 static const unsigned default_block_size = 8192;40 static const unsigned default_block_size = SURROUND_BUFSIZE; 41 41 // Gain of center and lfe channels in passive mode (sqrt 0.5) 42 42 static const float center_level = 0.707107; 43 43 -
mythtv/libs/libmythfreesurround/freesurround.h
21 21 22 22 #include "compat.h" // instead of sys/types.h, for MinGW compatibility 23 23 24 #define SURROUND_BUFSIZE 8192 25 24 26 class FreeSurround 25 27 { 26 28 public:
