1 /* 2 * MPEG Layer 3 handling 3 * 4 * Copyright (C) 2002 Eric Pouech 5 * Copyright (C) 2009 CodeWeavers, Aric Stewart 6 * Copyright (C) 2010 Kristofer Henriksson 7 * 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 */ 23 24 #include "config.h" 25 #include "wine/port.h" 26 27 #include <assert.h> 28 #include <stdarg.h> 29 #include <string.h> 30 31 #ifdef HAVE_MPG123_H 32 # include <mpg123.h> 33 #else 34 # ifdef HAVE_COREAUDIO_COREAUDIO_H 35 # include <CoreFoundation/CoreFoundation.h> 36 # include <CoreAudio/CoreAudio.h> 37 # endif 38 # ifdef HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H 39 # include <AudioToolbox/AudioConverter.h> 40 # endif 41 #endif 42 43 #include "windef.h" 44 #include "winbase.h" 45 #include "wingdi.h" 46 #include "winuser.h" 47 #include "winnls.h" 48 #include "mmsystem.h" 49 #include "mmreg.h" 50 #include "msacm.h" 51 #include "msacmdrv.h" 52 #include "wine/debug.h" 53 54 WINE_DEFAULT_DEBUG_CHANNEL(mpeg3); 55 56 /* table to list all supported formats... those are the basic ones. this 57 * also helps given a unique index to each of the supported formats 58 */ 59 typedef struct 60 { 61 int nChannels; 62 int nBits; 63 int rate; 64 } Format; 65 66 static const Format PCM_Formats[] = 67 { 68 {1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000}, 69 {1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025}, 70 {1, 8, 12000}, {2, 8, 12000}, {1, 16, 12000}, {2, 16, 12000}, 71 {1, 8, 16000}, {2, 8, 16000}, {1, 16, 16000}, {2, 16, 16000}, 72 {1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050}, 73 {1, 8, 24000}, {2, 8, 24000}, {1, 16, 24000}, {2, 16, 24000}, 74 {1, 8, 32000}, {2, 8, 32000}, {1, 16, 32000}, {2, 16, 32000}, 75 {1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100}, 76 {1, 8, 48000}, {2, 8, 48000}, {1, 16, 48000}, {2, 16, 48000} 77 }; 78 79 static const Format MPEG3_Formats[] = 80 { 81 {1, 0, 8000}, {2, 0, 8000}, 82 {1, 0, 11025}, {2, 0, 11025}, 83 {1, 0, 12000}, {2, 0, 12000}, 84 {1, 0, 16000}, {2, 0, 16000}, 85 {1, 0, 22050}, {2, 0, 22050}, 86 {1, 0, 24000}, {2, 0, 24000}, 87 {1, 0, 32000}, {2, 0, 32000}, 88 {1, 0, 44100}, {2, 0, 44100}, 89 {1, 0, 48000}, {2, 0, 48000} 90 }; 91 92 #define NUM_PCM_FORMATS (sizeof(PCM_Formats) / sizeof(PCM_Formats[0])) 93 #define NUM_MPEG3_FORMATS (sizeof(MPEG3_Formats) / sizeof(MPEG3_Formats[0])) 94 95 /*********************************************************************** 96 * MPEG3_GetFormatIndex 97 */ 98 static DWORD MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx) 99 { 100 int i, hi; 101 const Format *fmts; 102 103 switch (wfx->wFormatTag) 104 { 105 case WAVE_FORMAT_PCM: 106 hi = NUM_PCM_FORMATS; 107 fmts = PCM_Formats; 108 break; 109 case WAVE_FORMAT_MPEG: 110 case WAVE_FORMAT_MPEGLAYER3: 111 hi = NUM_MPEG3_FORMATS; 112 fmts = MPEG3_Formats; 113 break; 114 default: 115 return 0xFFFFFFFF; 116 } 117 118 for (i = 0; i < hi; i++) 119 { 120 if (wfx->nChannels == fmts[i].nChannels && 121 wfx->nSamplesPerSec == fmts[i].rate && 122 (wfx->wBitsPerSample == fmts[i].nBits || !fmts[i].nBits)) 123 return i; 124 } 125 126 return 0xFFFFFFFF; 127 } 128 129 #ifdef HAVE_MPG123_H 130 131 typedef struct tagAcmMpeg3Data 132 { 133 void (*convert)(PACMDRVSTREAMINSTANCE adsi, 134 const unsigned char*, LPDWORD, unsigned char*, LPDWORD); 135 mpg123_handle *mh; 136 } AcmMpeg3Data; 137 138 /*********************************************************************** 139 * MPEG3_drvOpen 140 */ 141 static LRESULT MPEG3_drvOpen(LPCSTR str) 142 { 143 mpg123_init(); 144 return 1; 145 } 146 147 /*********************************************************************** 148 * MPEG3_drvClose 149 */ 150 static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID) 151 { 152 mpg123_exit(); 153 return 1; 154 } 155 156 157 static void mp3_horse(PACMDRVSTREAMINSTANCE adsi, 158 const unsigned char* src, LPDWORD nsrc, 159 unsigned char* dst, LPDWORD ndst) 160 { 161 AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver; 162 int ret; 163 size_t size; 164 DWORD dpos = 0; 165 166 167 if (*nsrc > 0) 168 { 169 ret = mpg123_feed(amd->mh, src, *nsrc); 170 if (ret != MPG123_OK) 171 { 172 ERR("Error feeding data\n"); 173 *ndst = *nsrc = 0; 174 return; 175 } 176 } 177 178 do { 179 size = 0; 180 ret = mpg123_read(amd->mh, dst + dpos, *ndst - dpos, &size); 181 if (ret == MPG123_ERR) 182 { 183 FIXME("Error occurred during decoding!\n"); 184 *ndst = *nsrc = 0; 185 return; 186 } 187 188 if (ret == MPG123_NEW_FORMAT) 189 { 190 long rate; 191 int channels, enc; 192 mpg123_getformat(amd->mh, &rate, &channels, &enc); 193 TRACE("New format: %li Hz, %i channels, encoding value %i\n", rate, channels, enc); 194 } 195 dpos += size; 196 if (dpos >= *ndst) break; 197 } while (ret != MPG123_ERR && ret != MPG123_NEED_MORE); 198 *ndst = dpos; 199 } 200 201 /*********************************************************************** 202 * MPEG3_Reset 203 * 204 */ 205 static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad) 206 { 207 mpg123_feedseek(aad->mh, 0, SEEK_SET, NULL); 208 mpg123_close(aad->mh); 209 mpg123_open_feed(aad->mh); 210 } 211 212 /*********************************************************************** 213 * MPEG3_StreamOpen 214 * 215 */ 216 static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi) 217 { 218 LRESULT error = MMSYSERR_NOTSUPPORTED; 219 AcmMpeg3Data* aad; 220 int err; 221 222 assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC)); 223 224 if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF || 225 MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF) 226 return ACMERR_NOTPOSSIBLE; 227 228 aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data)); 229 if (aad == 0) return MMSYSERR_NOMEM; 230 231 adsi->dwDriver = (DWORD_PTR)aad; 232 233 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && 234 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) 235 { 236 goto theEnd; 237 } 238 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 || 239 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) && 240 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) 241 { 242 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3) 243 { 244 MPEGLAYER3WAVEFORMAT *formatmp3 = (MPEGLAYER3WAVEFORMAT *)adsi->pwfxSrc; 245 246 if (adsi->pwfxSrc->cbSize < MPEGLAYER3_WFX_EXTRA_BYTES || 247 formatmp3->wID != MPEGLAYER3_ID_MPEG) 248 { 249 error = ACMERR_NOTPOSSIBLE; 250 goto theEnd; 251 } 252 } 253 254 /* resampling or mono <=> stereo not available 255 * MPEG3 algo only define 16 bit per sample output 256 */ 257 if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec || 258 adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels || 259 adsi->pwfxDst->wBitsPerSample != 16) 260 goto theEnd; 261 aad->convert = mp3_horse; 262 aad->mh = mpg123_new(NULL,&err); 263 mpg123_open_feed(aad->mh); 264 265 #if MPG123_API_VERSION >= 31 /* needed for MPG123_IGNORE_FRAMEINFO enum value */ 266 /* mpg123 may find a XING header in the mp3 and use that information 267 * to ask for seeks in order to read specific frames in the file. 268 * We cannot allow that since the caller application is feeding us. 269 * This fixes problems for mp3 files encoded with LAME (bug 42361) 270 */ 271 mpg123_param(aad->mh, MPG123_ADD_FLAGS, MPG123_IGNORE_INFOFRAME, 0); 272 #endif 273 } 274 else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && 275 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 || 276 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG)) 277 { 278 WARN("Encoding to MPEG is not supported\n"); 279 goto theEnd; 280 } 281 else goto theEnd; 282 MPEG3_Reset(adsi, aad); 283 284 return MMSYSERR_NOERROR; 285 286 theEnd: 287 HeapFree(GetProcessHeap(), 0, aad); 288 adsi->dwDriver = 0L; 289 return error; 290 } 291 292 /*********************************************************************** 293 * MPEG3_StreamClose 294 * 295 */ 296 static LRESULT MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi) 297 { 298 mpg123_close(((AcmMpeg3Data*)adsi->dwDriver)->mh); 299 mpg123_delete(((AcmMpeg3Data*)adsi->dwDriver)->mh); 300 HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver); 301 return MMSYSERR_NOERROR; 302 } 303 304 #elif defined(HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H) 305 306 static const unsigned short Mp3BitRates[2][16] = 307 { 308 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}, 309 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0} 310 }; 311 312 static const unsigned short Mp3SampleRates[2][4] = 313 { 314 {44100, 48000, 32000, 0}, 315 {22050, 24000, 16000, 0} 316 }; 317 318 typedef struct tagAcmMpeg3Data 319 { 320 LRESULT (*convert)(PACMDRVSTREAMINSTANCE adsi, unsigned char*, 321 LPDWORD, unsigned char*, LPDWORD); 322 AudioConverterRef acr; 323 AudioStreamBasicDescription in,out; 324 325 AudioBufferList outBuffer; 326 AudioBuffer inBuffer; 327 328 SInt32 tagBytesLeft; 329 330 UInt32 NumberPackets; 331 AudioStreamPacketDescription *PacketDescriptions; 332 } AcmMpeg3Data; 333 334 /*********************************************************************** 335 * MPEG3_drvOpen 336 */ 337 static LRESULT MPEG3_drvOpen(LPCSTR str) 338 { 339 return 1; 340 } 341 342 /*********************************************************************** 343 * MPEG3_drvClose 344 */ 345 static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID) 346 { 347 return 1; 348 } 349 350 /* 351 When it asks for data, give it all we have. If we have no data, we assume 352 we will in the future, so give it no packets and return an error, which 353 signals that we will have more later. 354 */ 355 static OSStatus Mp3AudioConverterComplexInputDataProc( 356 AudioConverterRef inAudioConverter, 357 UInt32 *ioNumberDataPackets, 358 AudioBufferList *ioData, 359 AudioStreamPacketDescription **outDataPacketDescription, 360 void *inUserData 361 ) 362 { 363 AcmMpeg3Data *amd = (AcmMpeg3Data*)inUserData; 364 365 if (amd->inBuffer.mDataByteSize > 0) 366 { 367 *ioNumberDataPackets = amd->NumberPackets; 368 ioData->mNumberBuffers = 1; 369 ioData->mBuffers[0] = amd->inBuffer; 370 amd->inBuffer.mDataByteSize = 0; 371 if (outDataPacketDescription) 372 *outDataPacketDescription = amd->PacketDescriptions; 373 return noErr; 374 } 375 else 376 { 377 *ioNumberDataPackets = 0; 378 return -74; 379 } 380 } 381 382 /* 383 Get the length of the current frame. We need to be at the start of a 384 frame now. The buffer must have at least the four bytes for the header. 385 */ 386 static SInt32 Mp3GetPacketLength(const unsigned char* src) 387 { 388 unsigned char mpegv; 389 unsigned short brate, srate; 390 unsigned int size; 391 392 /* 393 Check that our position looks like an MP3 header and see which type 394 of MP3 file we have. 395 */ 396 if (src[0] == 0xff && src[1] >> 1 == 0x7d) mpegv = 0; /* MPEG-1 File */ 397 else if (src[0] == 0xff && src[1] >> 1 == 0x79) mpegv = 1; /* MPEG-2 File */ 398 else return -1; 399 400 /* Fill in bit rate and sample rate. */ 401 brate = Mp3BitRates[mpegv][(src[2] & 0xf0) >> 4]; 402 srate = Mp3SampleRates[mpegv][(src[2] & 0xc) >> 2]; 403 404 /* Certain values for bit rate and sample rate are invalid. */ 405 if (brate == 0 || srate == 0) return -1; 406 407 /* Compute frame size, round down */ 408 size = 72 * (2 - mpegv) * brate * 1000 / srate; 409 410 /* If there is padding, add one byte */ 411 if (src[2] & 0x2) return size + 1; 412 else return size; 413 } 414 415 /* 416 Apple's AudioFileStream does weird things so we deal with parsing the 417 file ourselves. It was also designed for a different use case, so this 418 is not unexpected. We expect to have MP3 data as input (i.e. we can only 419 deal with MPEG-1 or MPEG-2 Layer III), which simplifies parsing a bit. We 420 understand the ID3v2 header and skip over it. Whenever we have data we 421 want to skip at the beginning of the input, we do this by setting *ndst=0 422 and *nsrc to the length of the unwanted data and return no error. 423 */ 424 static LRESULT mp3_leopard_horse(PACMDRVSTREAMINSTANCE adsi, 425 unsigned char* src, LPDWORD nsrc, 426 unsigned char* dst, LPDWORD ndst) 427 { 428 OSStatus err; 429 UInt32 size, aspdi, synci, syncSkip; 430 short framelen[4]; 431 const unsigned char* psrc; 432 AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver; 433 434 TRACE("ndst %u %p <- %u %p\n", *ndst, dst, *nsrc, src); 435 436 TRACE("First 16 bytes to input: %s\n", wine_dbgstr_an((const char *)src, 16)); 437 438 /* Parse ID3 tag */ 439 if (!memcmp(src, "ID3", 3) && amd->tagBytesLeft == -1) 440 { 441 amd->tagBytesLeft = (src[6] << 21) + (src[7] << 14) + (src[8] << 7) + src[9]; 442 if (src[5] & 0x10) amd->tagBytesLeft += 20; /* There is a footer */ 443 else amd->tagBytesLeft += 10; 444 } 445 446 /* Consume the tag */ 447 if (amd->tagBytesLeft >= (SInt32)*nsrc) 448 { 449 *ndst = 0; 450 amd->tagBytesLeft -= *nsrc; 451 452 TRACE("All %d bytes of source data is ID3 tag\n", *nsrc); 453 return MMSYSERR_NOERROR; 454 } 455 else if (amd->tagBytesLeft > 0) 456 { 457 src += amd->tagBytesLeft; 458 *nsrc -= amd->tagBytesLeft; 459 TRACE("Skipping %ld for ID3 tag\n", amd->tagBytesLeft); 460 } 461 462 /* 463 Sync to initial MP3 frame. The largest possible MP3 frame is 1440. 464 Thus, in the first 1440 bytes we must find the beginning of 3 valid 465 frames in a row unless we reach the end of the file first. 466 */ 467 syncSkip = 0; 468 for (psrc = src; psrc <= src + *nsrc - 4 && psrc < src + 1440; psrc++) 469 { 470 framelen[0] = 0; 471 for (synci = 1; 472 synci < 4 && psrc + framelen[synci-1] < src + *nsrc - 4; 473 synci++) 474 { 475 framelen[synci] = Mp3GetPacketLength(psrc + framelen[synci-1]); 476 if (framelen[synci] == -1) 477 { 478 synci = 0; 479 break; 480 } 481 framelen[synci] += framelen[synci-1]; 482 } 483 if (synci > 0) /* We synced successfully */ 484 { 485 if (psrc - src > 0) 486 { 487 syncSkip = psrc - src; 488 src += syncSkip; 489 *nsrc -= syncSkip; 490 TRACE("Skipping %ld for frame sync\n", syncSkip); 491 } 492 break; 493 } 494 } 495 496 if (Mp3GetPacketLength(src) == -1) 497 { 498 *ndst = *nsrc = 0; 499 ERR("Frame sync failed. Cannot play file.\n"); 500 return MMSYSERR_ERROR; 501 } 502 503 /* 504 Fill in frame descriptions for all frames. We use an extra pointer 505 to keep track of our position in the input. 506 */ 507 508 amd->NumberPackets = 25; /* This is the initial array capacity */ 509 amd->PacketDescriptions = HeapAlloc(GetProcessHeap(), 0, amd->NumberPackets * sizeof(AudioStreamPacketDescription)); 510 if (amd->PacketDescriptions == 0) return MMSYSERR_NOMEM; 511 512 for (aspdi = 0, psrc = src; 513 psrc <= src + *nsrc - 4; 514 psrc += amd->PacketDescriptions[aspdi].mDataByteSize, aspdi++) 515 { 516 /* Return an error if we can't read the frame header */ 517 if (Mp3GetPacketLength(psrc) == -1) 518 { 519 *ndst = *nsrc = 0; 520 ERR("Invalid header at %p.\n", psrc); 521 HeapFree(GetProcessHeap(), 0, amd->PacketDescriptions); 522 return MMSYSERR_ERROR; 523 } 524 525 /* If we run out of space, double size and reallocate */ 526 if (aspdi >= amd->NumberPackets) 527 { 528 amd->NumberPackets *= 2; 529 amd->PacketDescriptions = HeapReAlloc(GetProcessHeap(), 0, amd->PacketDescriptions, amd->NumberPackets * sizeof(AudioStreamPacketDescription)); 530 if (amd->PacketDescriptions == 0) return MMSYSERR_NOMEM; 531 } 532 533 /* Fill in packet data */ 534 amd->PacketDescriptions[aspdi].mStartOffset = psrc - src; 535 amd->PacketDescriptions[aspdi].mVariableFramesInPacket = 0; 536 amd->PacketDescriptions[aspdi].mDataByteSize = Mp3GetPacketLength(psrc); 537 538 /* If this brings us past the end, the last one doesn't count */ 539 if (psrc + amd->PacketDescriptions[aspdi].mDataByteSize > src + *nsrc) break; 540 } 541 542 /* Fill in correct number of frames */ 543 amd->NumberPackets = aspdi; 544 545 /* Adjust nsrc to only include full frames */ 546 *nsrc = psrc - src; 547 548 amd->inBuffer.mDataByteSize = *nsrc; 549 amd->inBuffer.mData = src; 550 amd->inBuffer.mNumberChannels = amd->in.mChannelsPerFrame; 551 552 amd->outBuffer.mNumberBuffers = 1; 553 amd->outBuffer.mBuffers[0].mDataByteSize = *ndst; 554 amd->outBuffer.mBuffers[0].mData = dst; 555 amd->outBuffer.mBuffers[0].mNumberChannels = amd->out.mChannelsPerFrame; 556 557 /* Convert the data */ 558 size = amd->outBuffer.mBuffers[0].mDataByteSize / amd->out.mBytesPerPacket; 559 err = AudioConverterFillComplexBuffer(amd->acr, Mp3AudioConverterComplexInputDataProc, amd, &size, &amd->outBuffer, 0); 560 561 HeapFree(GetProcessHeap(), 0, amd->PacketDescriptions); 562 563 /* Add skipped bytes back into *nsrc */ 564 if (amd->tagBytesLeft > 0) 565 { 566 *nsrc += amd->tagBytesLeft; 567 amd->tagBytesLeft = 0; 568 } 569 *nsrc += syncSkip; 570 571 if (err != noErr && err != -74) 572 { 573 *ndst = *nsrc = 0; 574 ERR("Feed Error: %ld\n", err); 575 return MMSYSERR_ERROR; 576 } 577 578 *ndst = amd->outBuffer.mBuffers[0].mDataByteSize; 579 580 TRACE("convert %d -> %d\n", *nsrc, *ndst); 581 582 return MMSYSERR_NOERROR; 583 } 584 585 /*********************************************************************** 586 * MPEG3_Reset 587 * 588 */ 589 static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad) 590 { 591 AudioConverterReset(aad->acr); 592 } 593 594 /*********************************************************************** 595 * MPEG3_StreamOpen 596 * 597 */ 598 static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi) 599 { 600 AcmMpeg3Data* aad; 601 602 assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC)); 603 604 if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF || 605 MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF) 606 return ACMERR_NOTPOSSIBLE; 607 608 aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data)); 609 if (aad == 0) return MMSYSERR_NOMEM; 610 611 adsi->dwDriver = (DWORD_PTR)aad; 612 613 if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 || 614 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) && 615 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) 616 { 617 OSStatus err; 618 619 aad->in.mSampleRate = adsi->pwfxSrc->nSamplesPerSec; 620 aad->out.mSampleRate = adsi->pwfxDst->nSamplesPerSec; 621 aad->in.mBitsPerChannel = adsi->pwfxSrc->wBitsPerSample; 622 aad->out.mBitsPerChannel = adsi->pwfxDst->wBitsPerSample; 623 aad->in.mFormatID = kAudioFormatMPEGLayer3; 624 aad->out.mFormatID = kAudioFormatLinearPCM; 625 aad->in.mChannelsPerFrame = adsi->pwfxSrc->nChannels; 626 aad->out.mChannelsPerFrame = adsi->pwfxDst->nChannels; 627 aad->in.mFormatFlags = 0; 628 aad->out.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; 629 aad->in.mBytesPerFrame = 0; 630 aad->out.mBytesPerFrame = (aad->out.mBitsPerChannel * aad->out.mChannelsPerFrame) / 8; 631 aad->in.mBytesPerPacket = 0; 632 aad->out.mBytesPerPacket = aad->out.mBytesPerFrame; 633 aad->in.mFramesPerPacket = 0; 634 aad->out.mFramesPerPacket = 1; 635 aad->in.mReserved = aad->out.mReserved = 0; 636 637 aad->tagBytesLeft = -1; 638 639 aad->convert = mp3_leopard_horse; 640 641 err = AudioConverterNew(&aad->in, &aad->out, &aad->acr); 642 if (err != noErr) 643 { 644 ERR("Create failed: %ld\n", err); 645 } 646 else 647 { 648 MPEG3_Reset(adsi, aad); 649 650 return MMSYSERR_NOERROR; 651 } 652 } 653 654 HeapFree(GetProcessHeap(), 0, aad); 655 adsi->dwDriver = 0; 656 657 return MMSYSERR_NOTSUPPORTED; 658 } 659 660 /*********************************************************************** 661 * MPEG3_StreamClose 662 * 663 */ 664 static LRESULT MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi) 665 { 666 AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver; 667 668 AudioConverterDispose(amd->acr); 669 670 HeapFree(GetProcessHeap(), 0, amd); 671 adsi->dwDriver = 0; 672 673 return MMSYSERR_NOERROR; 674 } 675 676 #endif 677 678 /*********************************************************************** 679 * MPEG3_DriverDetails 680 * 681 */ 682 static LRESULT MPEG3_DriverDetails(PACMDRIVERDETAILSW add) 683 { 684 add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC; 685 add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED; 686 add->wMid = MM_FRAUNHOFER_IIS; 687 add->wPid = MM_FHGIIS_MPEGLAYER3_DECODE; 688 add->vdwACM = 0x01000000; 689 add->vdwDriver = 0x01000000; 690 add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; 691 add->cFormatTags = 3; /* PCM, MPEG3 */ 692 add->cFilterTags = 0; 693 add->hicon = NULL; 694 MultiByteToWideChar( CP_ACP, 0, "MPEG Layer-3 Codec", -1, 695 add->szShortName, sizeof(add->szShortName)/sizeof(WCHAR) ); 696 MultiByteToWideChar( CP_ACP, 0, "Wine MPEG3 decoder", -1, 697 add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) ); 698 MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1, 699 add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) ); 700 MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1, 701 add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) ); 702 add->szFeatures[0] = 0; 703 704 return MMSYSERR_NOERROR; 705 } 706 707 /*********************************************************************** 708 * MPEG3_FormatTagDetails 709 * 710 */ 711 static LRESULT MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery) 712 { 713 static const WCHAR szPcm[]={'P','C','M',0}; 714 static const WCHAR szMpeg3[]={'M','P','e','g','3',0}; 715 static const WCHAR szMpeg[]={'M','P','e','g',0}; 716 717 switch (dwQuery) 718 { 719 case ACM_FORMATTAGDETAILSF_INDEX: 720 if (aftd->dwFormatTagIndex > 2) return ACMERR_NOTPOSSIBLE; 721 break; 722 case ACM_FORMATTAGDETAILSF_LARGESTSIZE: 723 if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN) 724 { 725 aftd->dwFormatTagIndex = 2; /* WAVE_FORMAT_MPEG is biggest */ 726 break; 727 } 728 /* fall through */ 729 case ACM_FORMATTAGDETAILSF_FORMATTAG: 730 switch (aftd->dwFormatTag) 731 { 732 case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break; 733 case WAVE_FORMAT_MPEGLAYER3: aftd->dwFormatTagIndex = 1; break; 734 case WAVE_FORMAT_MPEG: aftd->dwFormatTagIndex = 2; break; 735 default: return ACMERR_NOTPOSSIBLE; 736 } 737 break; 738 default: 739 WARN("Unsupported query %08x\n", dwQuery); 740 return MMSYSERR_NOTSUPPORTED; 741 } 742 743 aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; 744 switch (aftd->dwFormatTagIndex) 745 { 746 case 0: 747 aftd->dwFormatTag = WAVE_FORMAT_PCM; 748 aftd->cbFormatSize = sizeof(PCMWAVEFORMAT); 749 aftd->cStandardFormats = NUM_PCM_FORMATS; 750 lstrcpyW(aftd->szFormatTag, szPcm); 751 break; 752 case 1: 753 aftd->dwFormatTag = WAVE_FORMAT_MPEGLAYER3; 754 aftd->cbFormatSize = sizeof(MPEGLAYER3WAVEFORMAT); 755 aftd->cStandardFormats = 0; 756 lstrcpyW(aftd->szFormatTag, szMpeg3); 757 break; 758 case 2: 759 aftd->dwFormatTag = WAVE_FORMAT_MPEG; 760 aftd->cbFormatSize = sizeof(MPEG1WAVEFORMAT); 761 aftd->cStandardFormats = 0; 762 lstrcpyW(aftd->szFormatTag, szMpeg); 763 break; 764 } 765 return MMSYSERR_NOERROR; 766 } 767 768 /*********************************************************************** 769 * MPEG3_FormatDetails 770 * 771 */ 772 static LRESULT MPEG3_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery) 773 { 774 switch (dwQuery) 775 { 776 case ACM_FORMATDETAILSF_FORMAT: 777 if (MPEG3_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE; 778 break; 779 case ACM_FORMATDETAILSF_INDEX: 780 afd->pwfx->wFormatTag = afd->dwFormatTag; 781 switch (afd->dwFormatTag) 782 { 783 case WAVE_FORMAT_PCM: 784 if (afd->dwFormatIndex >= NUM_PCM_FORMATS) return ACMERR_NOTPOSSIBLE; 785 afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels; 786 afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate; 787 afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits; 788 /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible 789 * afd->pwfx->cbSize = 0; 790 */ 791 afd->pwfx->nBlockAlign = 792 (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8; 793 afd->pwfx->nAvgBytesPerSec = 794 afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign; 795 break; 796 case WAVE_FORMAT_MPEGLAYER3: 797 case WAVE_FORMAT_MPEG: 798 WARN("Encoding to MPEG is not supported\n"); 799 return ACMERR_NOTPOSSIBLE; 800 default: 801 WARN("Unsupported tag %08x\n", afd->dwFormatTag); 802 return MMSYSERR_INVALPARAM; 803 } 804 break; 805 default: 806 WARN("Unsupported query %08x\n", dwQuery); 807 return MMSYSERR_NOTSUPPORTED; 808 } 809 afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; 810 afd->szFormat[0] = 0; /* let MSACM format this for us... */ 811 812 return MMSYSERR_NOERROR; 813 } 814 815 /*********************************************************************** 816 * MPEG3_FormatSuggest 817 * 818 */ 819 static LRESULT MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs) 820 { 821 /* some tests ... */ 822 if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) || 823 adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) || 824 MPEG3_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE; 825 /* FIXME: should do those tests against the real size (according to format tag */ 826 827 /* If no suggestion for destination, then copy source value */ 828 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS)) 829 adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels; 830 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC)) 831 adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec; 832 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE)) 833 adfs->pwfxDst->wBitsPerSample = 16; 834 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG)) 835 { 836 if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) 837 { 838 WARN("Encoding to MPEG is not supported\n"); 839 return ACMERR_NOTPOSSIBLE; 840 } 841 else 842 adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM; 843 } 844 845 /* check if result is ok */ 846 if (MPEG3_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE; 847 848 /* recompute other values */ 849 switch (adfs->pwfxDst->wFormatTag) 850 { 851 case WAVE_FORMAT_PCM: 852 adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8; 853 adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign; 854 break; 855 case WAVE_FORMAT_MPEG: 856 case WAVE_FORMAT_MPEGLAYER3: 857 WARN("Encoding to MPEG is not supported\n"); 858 return ACMERR_NOTPOSSIBLE; 859 break; 860 default: 861 FIXME("\n"); 862 break; 863 } 864 865 return MMSYSERR_NOERROR; 866 } 867 868 /*********************************************************************** 869 * MPEG3_StreamSize 870 * 871 */ 872 static LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss) 873 { 874 DWORD nblocks; 875 876 switch (adss->fdwSize) 877 { 878 case ACM_STREAMSIZEF_DESTINATION: 879 /* cbDstLength => cbSrcLength */ 880 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && 881 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 || 882 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG)) 883 { 884 nblocks = (adss->cbDstLength - 3000) / (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5); 885 if (nblocks == 0) 886 return ACMERR_NOTPOSSIBLE; 887 adss->cbSrcLength = nblocks * 1152 * adsi->pwfxSrc->nBlockAlign; 888 } 889 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 || 890 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) && 891 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) 892 { 893 nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * 1152); 894 if (nblocks == 0) 895 return ACMERR_NOTPOSSIBLE; 896 adss->cbSrcLength = nblocks * (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec); 897 } 898 else 899 { 900 return MMSYSERR_NOTSUPPORTED; 901 } 902 break; 903 case ACM_STREAMSIZEF_SOURCE: 904 /* cbSrcLength => cbDstLength */ 905 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && 906 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 || 907 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG)) 908 { 909 nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * 1152); 910 if (adss->cbSrcLength % (DWORD)(adsi->pwfxSrc->nBlockAlign * 1152)) 911 /* Round block count up. */ 912 nblocks++; 913 if (nblocks == 0) 914 return ACMERR_NOTPOSSIBLE; 915 adss->cbDstLength = 3000 + nblocks * (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5); 916 } 917 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 || 918 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) && 919 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) 920 { 921 nblocks = adss->cbSrcLength / (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec); 922 if (adss->cbSrcLength % (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec)) 923 /* Round block count up. */ 924 nblocks++; 925 if (nblocks == 0) 926 return ACMERR_NOTPOSSIBLE; 927 adss->cbDstLength = nblocks * 1152 * adsi->pwfxDst->nBlockAlign; 928 } 929 else 930 { 931 return MMSYSERR_NOTSUPPORTED; 932 } 933 break; 934 default: 935 WARN("Unsupported query %08x\n", adss->fdwSize); 936 return MMSYSERR_NOTSUPPORTED; 937 } 938 return MMSYSERR_NOERROR; 939 } 940 941 /*********************************************************************** 942 * MPEG3_StreamConvert 943 * 944 */ 945 static LRESULT MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh) 946 { 947 AcmMpeg3Data* aad = (AcmMpeg3Data*)adsi->dwDriver; 948 DWORD nsrc = adsh->cbSrcLength; 949 DWORD ndst = adsh->cbDstLength; 950 951 if (adsh->fdwConvert & 952 ~(ACM_STREAMCONVERTF_BLOCKALIGN| 953 ACM_STREAMCONVERTF_END| 954 ACM_STREAMCONVERTF_START)) 955 { 956 FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert); 957 } 958 /* ACM_STREAMCONVERTF_BLOCKALIGN 959 * currently all conversions are block aligned, so do nothing for this flag 960 * ACM_STREAMCONVERTF_END 961 * no pending data, so do nothing for this flag 962 */ 963 if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START)) 964 { 965 MPEG3_Reset(adsi, aad); 966 } 967 968 aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst); 969 adsh->cbSrcLengthUsed = nsrc; 970 adsh->cbDstLengthUsed = ndst; 971 972 return MMSYSERR_NOERROR; 973 } 974 975 /************************************************************************** 976 * MPEG3_DriverProc [exported] 977 */ 978 LRESULT CALLBACK MPEG3_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, 979 LPARAM dwParam1, LPARAM dwParam2) 980 { 981 TRACE("(%08lx %p %04x %08lx %08lx);\n", 982 dwDevID, hDriv, wMsg, dwParam1, dwParam2); 983 984 switch (wMsg) 985 { 986 case DRV_LOAD: return 1; 987 case DRV_FREE: return 1; 988 case DRV_OPEN: return MPEG3_drvOpen((LPSTR)dwParam1); 989 case DRV_CLOSE: return MPEG3_drvClose(dwDevID); 990 case DRV_ENABLE: return 1; 991 case DRV_DISABLE: return 1; 992 case DRV_QUERYCONFIGURE: return 1; 993 case DRV_CONFIGURE: MessageBoxA(0, "MPEG3 filter !", "Wine Driver", MB_OK); return 1; 994 case DRV_INSTALL: return DRVCNF_RESTART; 995 case DRV_REMOVE: return DRVCNF_RESTART; 996 997 case ACMDM_DRIVER_NOTIFY: 998 /* no caching from other ACM drivers is done so far */ 999 return MMSYSERR_NOERROR; 1000 1001 case ACMDM_DRIVER_DETAILS: 1002 return MPEG3_DriverDetails((PACMDRIVERDETAILSW)dwParam1); 1003 1004 case ACMDM_FORMATTAG_DETAILS: 1005 return MPEG3_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2); 1006 1007 case ACMDM_FORMAT_DETAILS: 1008 return MPEG3_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2); 1009 1010 case ACMDM_FORMAT_SUGGEST: 1011 return MPEG3_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1); 1012 1013 case ACMDM_STREAM_OPEN: 1014 return MPEG3_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1); 1015 1016 case ACMDM_STREAM_CLOSE: 1017 return MPEG3_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1); 1018 1019 case ACMDM_STREAM_SIZE: 1020 return MPEG3_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2); 1021 1022 case ACMDM_STREAM_CONVERT: 1023 return MPEG3_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2); 1024 1025 case ACMDM_HARDWARE_WAVE_CAPS_INPUT: 1026 case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT: 1027 /* this converter is not a hardware driver */ 1028 case ACMDM_FILTERTAG_DETAILS: 1029 case ACMDM_FILTER_DETAILS: 1030 /* this converter is not a filter */ 1031 case ACMDM_STREAM_RESET: 1032 /* only needed for asynchronous driver... we aren't, so just say it */ 1033 return MMSYSERR_NOTSUPPORTED; 1034 case ACMDM_STREAM_PREPARE: 1035 case ACMDM_STREAM_UNPREPARE: 1036 /* nothing special to do here... so don't do anything */ 1037 return MMSYSERR_NOERROR; 1038 1039 default: 1040 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2); 1041 } 1042 } 1043