| 84 | } |
| 85 | |
| 86 | bool LoadSample(char* pointer, int compSize, int uncompSize, int index) |
| 87 | { |
| 88 | if (index >= SOUND_MAX_SAMPLES) |
| 89 | { |
| 90 | TENLog("Sample index " + std::to_string(index) + " is larger than max. amount of samples", LogLevel::Warning); |
| 91 | return 0; |
| 92 | } |
| 93 | |
| 94 | if (pointer == nullptr || compSize <= 0) |
| 95 | { |
| 96 | TENLog("Sample size or memory address is incorrect for index " + std::to_string(index), LogLevel::Warning); |
| 97 | return 0; |
| 98 | } |
| 99 | |
| 100 | // Load and uncompress sample to 32-bit float format. |
| 101 | HSAMPLE sample = BASS_SampleLoad(true, pointer, 0, compSize, 1, SOUND_SAMPLE_FLAGS); |
| 102 | |
| 103 | if (!sample) |
| 104 | { |
| 105 | TENLog("Error loading sample " + std::to_string(index), LogLevel::Error); |
| 106 | return false; |
| 107 | } |
| 108 | |
| 109 | // Paranoid (c) TeslaRus |
| 110 | // Try to free sample before allocating new one. |
| 111 | Sound_FreeSample(index); |
| 112 | |
| 113 | BASS_SAMPLE info; |
| 114 | BASS_SampleGetInfo(sample, &info); |
| 115 | int finalLength = info.length + 44; // uncompSize is invalid after 16->32 bit conversion |
| 116 | |
| 117 | if (info.freq != 22050 || info.chans != 1) |
| 118 | { |
| 119 | TENLog("Wrong sample parameters, must be 22050 Hz Mono", LogLevel::Error); |
| 120 | return false; |
| 121 | } |
| 122 | |
| 123 | // Generate RIFF/WAV header to simplify loading sample data to stream. In case if RIFF/WAV header |
| 124 | // exists, stream could be completely created just by calling BASS_StreamCreateFile(). |
| 125 | char* uncompBuffer = new char[finalLength]; |
| 126 | ZeroMemory(uncompBuffer, finalLength); |
| 127 | memcpy(uncompBuffer, "RIFF\0\0\0\0WAVEfmt \20\0\0\0", 20); |
| 128 | memcpy(uncompBuffer + 36, "data\0\0\0\0", 8); |
| 129 | |
| 130 | WAVEFORMATEX *wf = (WAVEFORMATEX*)(uncompBuffer + 20); |
| 131 | |
| 132 | wf->wFormatTag = 3; |
| 133 | wf->nChannels = info.chans; |
| 134 | wf->wBitsPerSample = 32; |
| 135 | wf->nSamplesPerSec = info.freq; |
| 136 | wf->nBlockAlign = wf->nChannels * wf->wBitsPerSample / 8; |
| 137 | wf->nAvgBytesPerSec = wf->nSamplesPerSec * wf->nBlockAlign; |
| 138 | |
| 139 | // Copy raw PCM data from temporary sample buffer to actual buffer which will be used by engine. |
| 140 | BASS_SampleGetData(sample, uncompBuffer + 44); |
| 141 | BASS_SampleFree(sample); |
| 142 | |
| 143 | // Cut off trailing silence from samples to prevent gaps in looped playback |
no test coverage detected