00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <libplayercore/playercore.h>
00024 #include "audio_sample.h"
00025
00026 #include <stdlib.h>
00027 #include <iostream>
00028
00029 using namespace std;
00030
00032
00034
00035
00036 AudioSample::AudioSample (void)
00037 {
00038
00039 type = SAMPLE_TYPE_NONE;
00040
00041 numChannels = 0;
00042 sampleRate = 0;
00043 byteRate = 0;
00044 blockAlign = 0;
00045 bitsPerSample = 0;
00046 numFrames = 0;
00047
00048 position = 0;
00049 waveFile = NULL;
00050 filePath = NULL;
00051 headerSize = 0;
00052 dataLength = 0;
00053 data = NULL;
00054 }
00055
00056
00057 AudioSample::AudioSample (const player_audio_wav_t *source)
00058 {
00059
00060 type = SAMPLE_TYPE_NONE;
00061
00062 numChannels = 0;
00063 sampleRate = 0;
00064 byteRate = 0;
00065 blockAlign = 0;
00066 bitsPerSample = 0;
00067 numFrames = 0;
00068
00069 position = 0;
00070 waveFile = NULL;
00071 filePath = NULL;
00072 headerSize = 0;
00073 dataLength = 0;
00074 data = NULL;
00075
00076 if (!FromPlayer (source))
00077 PLAYER_ERROR ("unable to create audio sample from Player data");
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 AudioSample::AudioSample (const uint8_t *source, uint32_t length, uint16_t channels, uint32_t sr, uint16_t bps)
00087 {
00088
00089 type = SAMPLE_TYPE_MEM;
00090
00091 numChannels = channels;
00092 sampleRate = sr;
00093 bitsPerSample = bps;
00094
00095 blockAlign = numChannels * (bitsPerSample / 8);
00096 byteRate = sampleRate * blockAlign;
00097
00098
00099 position = 0;
00100 waveFile = NULL;
00101 filePath = NULL;
00102 headerSize = 0;
00103 dataLength = 0;
00104 data = NULL;
00105
00106
00107 if ((data = new uint8_t[length]) == NULL)
00108 {
00109 PLAYER_ERROR ("Failed to allocate memory for wave data");
00110 return;
00111 }
00112
00113 memcpy (data, source, length);
00114 dataLength = length;
00115 numFrames = dataLength / blockAlign;
00116 }
00117
00118
00119 AudioSample::~AudioSample (void)
00120 {
00121 if (waveFile != NULL)
00122 {
00123 if (type != SAMPLE_TYPE_FILE)
00124 PLAYER_WARN ("file descriptor not NULL for non-file sample");
00125 fclose (waveFile);
00126 }
00127 if (filePath != NULL)
00128 {
00129 if (type != SAMPLE_TYPE_FILE)
00130 PLAYER_WARN ("file path not NULL for non-file sample");
00131 free (filePath);
00132 }
00133 if (data != NULL)
00134 {
00135 if (type != SAMPLE_TYPE_MEM)
00136 PLAYER_WARN ("data not NULL for non-mem sample");
00137 delete[] data;
00138 }
00139 }
00140
00142
00144
00145
00146 void AudioSample::SetDataPosition (uint32_t newPosition)
00147 {
00148
00149 if ((newPosition * blockAlign) > dataLength)
00150 position = dataLength;
00151 else
00152
00153 position = newPosition * blockAlign;
00154 }
00155
00156 uint32_t AudioSample::GetDataPosition (void) const
00157 {
00158 return position / blockAlign;
00159 }
00160
00161 uint32_t AudioSample::GetDataLength (void) const
00162 {
00163 if (type == SAMPLE_TYPE_FILE || type == SAMPLE_TYPE_MEM)
00164 return dataLength / blockAlign;
00165 else
00166 return 0;
00167 }
00168
00169
00170
00171
00172
00173 int AudioSample::GetData (int frameCount, uint8_t *buffer)
00174 {
00175 int bytesCopied = 0;
00176
00177 if (buffer == NULL)
00178 {
00179
00180 PLAYER_WARN ("Can't copy data into a null buffer");
00181 return -1;
00182 }
00183
00184
00185 int bytesCount = frameCount * blockAlign;
00186
00187 if (type == SAMPLE_TYPE_NONE)
00188 {
00189 PLAYER_WARN ("Attempt to get data from an empty sample");
00190 return -1;
00191 }
00192 else if (type == SAMPLE_TYPE_FILE)
00193 {
00194
00195
00196 if (fseek (waveFile, headerSize + position, SEEK_SET) != 0)
00197 {
00198 PLAYER_ERROR1 ("Error seeking to current position in wave file: %s", strerror (errno));
00199 return -1;
00200 }
00201
00202 int bytesToCopy = (position + bytesCount) > dataLength ? (dataLength - position) : bytesCount;
00203
00204 if ((bytesCopied = fread (buffer, 1, bytesToCopy, waveFile)) == 0)
00205 {
00206 if (feof (waveFile))
00207 PLAYER_ERROR ("End of file reading wave data");
00208 else
00209 PLAYER_ERROR1 ("Error reading wave data from file: %s", strerror (errno));
00210 return 0;
00211 }
00212 else if (bytesCopied < bytesToCopy)
00213 {
00214 PLAYER_ERROR1 ("Error reading wave data from file (didn't get enough bytes): %s\n", strerror (errno));
00215
00216 }
00217 }
00218 else if (type == SAMPLE_TYPE_MEM)
00219 {
00220
00221 if (dataLength == 0)
00222 return 0;
00223
00224 int bytesToCopy = (position + bytesCount) > dataLength ? (dataLength - position) : bytesCount;
00225
00226 memcpy (buffer, &data[position], bytesToCopy);
00227 bytesCopied = bytesToCopy;
00228 }
00229
00230
00231 position += bytesCopied;
00232
00233 return bytesCopied / blockAlign;
00234 }
00235
00236
00237 void AudioSample::ClearSample (void)
00238 {
00239
00240 if (type == SAMPLE_TYPE_FILE)
00241 {
00242 if (waveFile != NULL)
00243 fclose (waveFile);
00244 if (filePath != NULL)
00245 free (filePath);
00246 }
00247
00248 else if (type == SAMPLE_TYPE_MEM)
00249 {
00250 if (data != NULL)
00251 delete[] data;
00252 }
00253
00254
00255
00256
00257 type = SAMPLE_TYPE_NONE;
00258
00259 numChannels = 0;
00260 sampleRate = 0;
00261 byteRate = 0;
00262 blockAlign = 0;
00263 bitsPerSample = 0;
00264 numFrames = 0;
00265
00266 position = 0;
00267 waveFile = NULL;
00268 filePath = NULL;
00269 headerSize = 0;
00270 dataLength = 0;
00271 data = NULL;
00272 }
00273
00274
00275
00276 bool AudioSample::FillSilence (uint32_t time)
00277 {
00278
00279 if (type != SAMPLE_TYPE_NONE)
00280 {
00281 PLAYER_ERROR ("Tried to set non-empty sample to silence");
00282 return false;
00283 }
00284
00285
00286 dataLength = static_cast<uint32_t> ((static_cast<double> (time) / 1000.0f) * byteRate);
00287 if ((data = new uint8_t[dataLength]) == NULL)
00288 {
00289 PLAYER_ERROR ("Failed to allocate memory for wave data");
00290 return false;
00291 }
00292
00293 memset (data, 0, dataLength);
00294 numFrames = dataLength / blockAlign;
00295
00296
00297 type = SAMPLE_TYPE_MEM;
00298
00299 return true;
00300 }
00301
00303
00305
00306
00307
00308
00309 bool AudioSample::ToPlayer (player_audio_wav_t *dest)
00310 {
00311
00312
00313 if (type == SAMPLE_TYPE_NONE || (type == SAMPLE_TYPE_MEM && data == NULL) || (type == SAMPLE_TYPE_FILE && filePath == NULL))
00314 {
00315 PLAYER_WARN ("No sample to convert to player format");
00316 return false;
00317 }
00318
00319
00320 dest->format = PLAYER_AUDIO_FORMAT_RAW;
00321 if (numChannels == 2)
00322 dest->format |= PLAYER_AUDIO_STEREO;
00323 else if (numChannels != 1)
00324 {
00325 PLAYER_ERROR ("Cannot convert wave to player struct: wrong number of channels");
00326 return false;
00327 }
00328 switch (sampleRate)
00329 {
00330 case 11025:
00331 dest->format |= PLAYER_AUDIO_FREQ_11k;
00332 break;
00333 case 22050:
00334 dest->format |= PLAYER_AUDIO_FREQ_22k;
00335 break;
00336 case 44100:
00337 dest->format |= PLAYER_AUDIO_FREQ_44k;
00338 break;
00339 case 48000:
00340 dest->format |= PLAYER_AUDIO_FREQ_48k;
00341 break;
00342 default:
00343 PLAYER_ERROR ("Cannot convert wave to player struct: wrong sample rate");
00344 return false;
00345 }
00346
00347 switch (bitsPerSample)
00348 {
00349 case 8:
00350 dest->format |= PLAYER_AUDIO_8BIT;
00351 break;
00352 case 16:
00353 dest->format |= PLAYER_AUDIO_16BIT;
00354 break;
00355 case 24:
00356 dest->format |= PLAYER_AUDIO_24BIT;
00357 break;
00358 default:
00359 PLAYER_ERROR ("Cannot convert wave to player struct: wrong format (bits per sample)");
00360 return false;
00361 }
00362
00363
00364 uint32_t framesToCopy = PLAYER_MAX_MESSAGE_SIZE / blockAlign;
00365 if (numFrames < framesToCopy)
00366 framesToCopy = numFrames;
00367 if (type == SAMPLE_TYPE_FILE)
00368 {
00369
00370 uint32_t currentPos = GetDataPosition ();
00371
00372 SetDataPosition (0);
00373
00374 printf ("copied %d frames\n", GetData (framesToCopy, dest->data));
00375
00376 SetDataPosition (currentPos);
00377 }
00378 else
00379 {
00380
00381 memcpy (&dest->data, data, framesToCopy * blockAlign);
00382 }
00383 dest->data_count = framesToCopy * blockAlign;
00384
00385 return true;
00386 }
00387
00388 bool AudioSample::FromPlayer (const player_audio_wav_t *source)
00389 {
00390
00391 if ((source->format & PLAYER_AUDIO_FORMAT_BITS) != PLAYER_AUDIO_FORMAT_RAW)
00392 {
00393
00394 PLAYER_ERROR ("Cannot play non-raw audio data");
00395 return false;
00396 }
00397
00398
00399 ClearSample ();
00400
00401 if (source->format & PLAYER_AUDIO_STEREO)
00402 numChannels = 2;
00403 else
00404 numChannels = 1;
00405
00406 if ((source->format & PLAYER_AUDIO_FREQ) == PLAYER_AUDIO_FREQ_11k)
00407 sampleRate = 11025;
00408 else if ((source->format & PLAYER_AUDIO_FREQ) == PLAYER_AUDIO_FREQ_22k)
00409 sampleRate = 22050;
00410 else if ((source->format & PLAYER_AUDIO_FREQ) == PLAYER_AUDIO_FREQ_44k)
00411 sampleRate = 44100;
00412 else if ((source->format & PLAYER_AUDIO_FREQ) == PLAYER_AUDIO_FREQ_48k)
00413 sampleRate = 48000;
00414
00415 if ((source->format & PLAYER_AUDIO_BITS) == PLAYER_AUDIO_8BIT)
00416 {
00417 bitsPerSample = 8;
00418 }
00419 else if ((source->format & PLAYER_AUDIO_BITS) == PLAYER_AUDIO_16BIT)
00420 {
00421 bitsPerSample = 16;
00422 }
00423 else if ((source->format & PLAYER_AUDIO_BITS) == PLAYER_AUDIO_24BIT)
00424 {
00425 bitsPerSample = 24;
00426 }
00427
00428
00429 blockAlign = numChannels * (bitsPerSample / 8);
00430 byteRate = sampleRate * blockAlign;
00431
00432
00433 if ((data = new uint8_t[source->data_count]) == NULL)
00434 {
00435 PLAYER_ERROR ("Failed to allocate memory for wave data");
00436 return false;
00437 }
00438
00439 memcpy (data, source->data, source->data_count);
00440 dataLength = source->data_count;
00441 numFrames = dataLength / blockAlign;
00442
00443
00444 type = SAMPLE_TYPE_MEM;
00445
00446 return true;
00447 }
00448
00450
00452
00453
00454
00455
00456 bool AudioSample::LoadFile (const char *fileName)
00457 {
00458 char tag[5];
00459 uint16_t tempUShort = 0;
00460 uint32_t tempUInt = 0, subChunk1Size = 0;
00461
00462
00463 ClearSample ();
00464
00465
00466 if ((waveFile = fopen (fileName, "r")) == NULL)
00467 {
00468 PLAYER_ERROR1 ("Couldn't open wave file for reading: %s", strerror (errno));
00469 return false;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 if (fgets (tag, 5, waveFile) == NULL)
00481 {
00482 PLAYER_ERROR ("Error reading tag from wave file");
00483 return false;
00484 }
00485 if (strcmp (tag, "RIFF") != 0)
00486 {
00487 PLAYER_ERROR ("Bad WAV format: missing RIFF tag");
00488 return false;
00489 }
00490
00491 if (fread (&tempUInt, 4, 1, waveFile) != 1)
00492 {
00493 if (feof (waveFile))
00494 PLAYER_ERROR ("End of file reading WAV header");
00495 else
00496 PLAYER_ERROR ("Error reading WAV header");
00497 return false;
00498 }
00499
00500
00501 if (tempUInt < 36)
00502 {
00503 PLAYER_ERROR ("WAV file too short: missing chunk information");
00504 return false;
00505 }
00506
00507 if (fgets (tag, 5, waveFile) == NULL)
00508 {
00509 PLAYER_ERROR ("Error reading tag from wave file");
00510 return false;
00511 }
00512 if (strcmp (tag, "WAVE") != 0)
00513 {
00514 PLAYER_ERROR ("Bad WAV format: missing WAVE tag");
00515 return false;
00516 }
00517
00518
00519 if (fgets (tag, 5, waveFile) == NULL)
00520 {
00521 PLAYER_ERROR ("Error reading tag from wave file");
00522 return false;
00523 }
00524 if (strcmp (tag, "fmt ") != 0)
00525 {
00526 PLAYER_ERROR ("Bad WAV format: missing fmt tag");
00527 return false;
00528 }
00529
00530
00531 if (fread (&subChunk1Size, 4, 1, waveFile) != 1)
00532 {
00533 if (feof (waveFile))
00534 PLAYER_ERROR ("End of file reading WAV format");
00535 else
00536 PLAYER_ERROR ("Error reading WAV format");
00537 return false;
00538 }
00539 if (subChunk1Size != 16 && subChunk1Size != 18)
00540 {
00541 PLAYER_ERROR ("WAV file too short: missing chunk information");
00542 return false;
00543 }
00544
00545 if (fread (&tempUShort, 2, 1, waveFile) != 1)
00546 {
00547 if (feof (waveFile))
00548 PLAYER_ERROR ("End of file reading WAV format");
00549 else
00550 PLAYER_ERROR ("Error reading WAV format");
00551 return false;
00552 }
00553 if (tempUShort != 1)
00554 {
00555 PLAYER_ERROR ("WAV file not in PCM format");
00556 return false;
00557 }
00558
00559
00560 if (fread (&numChannels, 2, 1, waveFile) != 1)
00561 {
00562 if (feof (waveFile))
00563 PLAYER_ERROR ("End of file reading WAV num channels");
00564 else
00565 PLAYER_ERROR ("Error reading WAV num channels");
00566 ClearSample ();
00567 return false;
00568 }
00569
00570 if (fread (&sampleRate, 4, 1, waveFile) != 1)
00571 {
00572 if (feof (waveFile))
00573 PLAYER_ERROR ("End of file reading WAV sample rate");
00574 else
00575 PLAYER_ERROR ("Error reading WAV sample rate");
00576 ClearSample ();
00577 return false;
00578 }
00579
00580 if (fread (&byteRate, 4, 1, waveFile) != 1)
00581 {
00582 if (feof (waveFile))
00583 PLAYER_ERROR ("End of file reading WAV byte rate");
00584 else
00585 PLAYER_ERROR ("Error reading WAV byte rate");
00586 ClearSample ();
00587 return false;
00588 }
00589
00590 if (fread (&blockAlign, 2, 1, waveFile) != 1)
00591 {
00592 if (feof (waveFile))
00593 PLAYER_ERROR ("End of file reading WAV block align");
00594 else
00595 PLAYER_ERROR ("Error reading WAV block align");
00596 ClearSample ();
00597 return false;
00598 }
00599
00600 if (fread (&bitsPerSample, 2, 1, waveFile) != 1)
00601 {
00602 if (feof (waveFile))
00603 PLAYER_ERROR ("End of file reading WAV bits per sample");
00604 else
00605 PLAYER_ERROR ("Error reading WAV bits per sample");
00606 ClearSample ();
00607 return false;
00608 }
00609
00610 if (subChunk1Size == 18)
00611 {
00612 if (fread (&tempUShort, 2, 1, waveFile) != 1)
00613 {
00614 if (feof (waveFile))
00615 PLAYER_ERROR ("End of file reading blank 2 bytes");
00616 else
00617 PLAYER_ERROR ("Error reading WAV blank 2 bytes");
00618 ClearSample ();
00619 return false;
00620 }
00621 }
00622
00623
00624 if (fgets (tag, 5, waveFile) == NULL)
00625 {
00626 PLAYER_ERROR ("Error reading tag from wave file");
00627 ClearSample ();
00628 return false;
00629 }
00630 if (strcmp (tag, "data") != 0)
00631 {
00632 PLAYER_ERROR ("Bad WAV format: missing data tag");
00633 ClearSample ();
00634 return false;
00635 }
00636
00637 if (fread (&dataLength, 4, 1, waveFile) != 1)
00638 {
00639 if (feof (waveFile))
00640 PLAYER_ERROR ("End of file reading WAV data size");
00641 else
00642 PLAYER_ERROR ("Error reading WAV data size");
00643 ClearSample ();
00644 return false;
00645 }
00646
00647
00648
00649 headerSize = ftell (waveFile);
00650
00651 filePath = strdup (fileName);
00652
00653
00654 fseek (waveFile, 0, SEEK_END);
00655 dataLength = ftell (waveFile) - headerSize;
00656
00657 fseek (waveFile, headerSize, SEEK_SET);
00658
00659 numFrames = dataLength / (numChannels * (bitsPerSample / 8));
00660
00661 type = SAMPLE_TYPE_FILE;
00662
00663 return true;
00664 }
00665
00666 void AudioSample::CloseFile (void)
00667 {
00668
00669 ClearSample ();
00670 }
00671
00673
00675
00676
00677
00678
00679 bool AudioSample::SameFormat (const AudioSample *rhs)
00680 {
00681 if (!rhs || type == SAMPLE_TYPE_NONE)
00682 return false;
00683 if (numChannels == rhs->GetNumChannels () &&
00684 sampleRate == rhs->GetSampleRate () &&
00685 bitsPerSample == rhs->GetBitsPerSample ())
00686 return true;
00687 return false;
00688 }
00689
00690
00691
00692 void AudioSample::CopyFormat (const AudioSample *rhs)
00693 {
00694 if (!rhs || type == SAMPLE_TYPE_NONE)
00695 return;
00696 numChannels = rhs->GetNumChannels ();
00697 sampleRate = rhs->GetSampleRate ();
00698 byteRate = rhs->GetByteRate ();
00699 blockAlign = rhs->GetBlockAlign ();
00700 bitsPerSample = rhs->GetBitsPerSample ();
00701 }
00702
00704
00706
00707 void AudioSample::PrintWaveInfo (void)
00708 {
00709 if (type == SAMPLE_TYPE_FILE)
00710 cout << "File sample, path: " << filePath << endl;
00711 else if (type == SAMPLE_TYPE_MEM)
00712 cout << "Memory sample" << endl;
00713 else
00714 cout << "Empty sample" << endl;
00715 cout << "Num channels:\t" << numChannels << endl;
00716 cout << "Sample rate:\t" << sampleRate << endl;
00717 cout << "Byte rate:\t" << byteRate << endl;
00718 cout << "Block align:\t" << blockAlign << endl;
00719 cout << "Format:\t\t" << endl;
00720 switch (bitsPerSample)
00721 {
00722 case 8:
00723 cout << "Unsigned 8 bit" << endl;
00724 break;
00725 case 16:
00726 cout << "Signed 16 bit little-endian" << endl;
00727 break;
00728 case 24:
00729 if ((blockAlign / numChannels) == 3)
00730 cout << "Signed 24 bit 3-byte little-endian" << endl;
00731 else
00732 cout << "Signed 24 bit little-endian" << endl;
00733 break;
00734 case 32:
00735 cout << "Signed 32 bit little-endian" << endl;
00736 break;
00737 default:
00738 cout << "Unplayable format: " << bitsPerSample << " bit" << endl;
00739 }
00740 cout << "Num frames:\t" << numFrames << endl;
00741 cout << "Data length:\t" << dataLength << endl;
00742 if (type == SAMPLE_TYPE_FILE)
00743 cout << "Frames start at:\t" << headerSize << endl;
00744 }