Skip to content
Snippets Groups Projects
Commit 5bae58e0 authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #8545: fixed broken ringtone

The buffer size in audio loop wasn't being updated properly.
parent 1e43fea4
No related branches found
No related tags found
No related merge requests found
...@@ -33,7 +33,8 @@ ...@@ -33,7 +33,8 @@
*/ */
#include "audioloop.h" #include "audioloop.h"
#include <math.h> #include <cmath>
#include <numeric>
#include <cstring> #include <cstring>
#include <cassert> #include <cassert>
...@@ -54,6 +55,9 @@ AudioLoop::getNext(SFLDataFormat* output, size_t total_samples, short volume) ...@@ -54,6 +55,9 @@ AudioLoop::getNext(SFLDataFormat* output, size_t total_samples, short volume)
if (size_ == 0) { if (size_ == 0) {
ERROR("AudioLoop: Error: Audio loop size is 0"); ERROR("AudioLoop: Error: Audio loop size is 0");
return; return;
} else if (pos < size_) {
ERROR("AudioLoop: Error: Invalid loop position %d", pos);
return;
} }
while (total_samples) { while (total_samples) {
......
...@@ -62,18 +62,17 @@ SamplerateConverter::Short2FloatArray(const short *in, float *out, int len) ...@@ -62,18 +62,17 @@ SamplerateConverter::Short2FloatArray(const short *in, float *out, int len)
out[len] = (float) in[len] * .000030517578125f; out[len] = (float) in[len] * .000030517578125f;
} }
void SamplerateConverter::resample(SFLDataFormat* dataIn , SFLDataFormat* dataOut , int inputFreq , int outputFreq , int nbSamples) void SamplerateConverter::resample(SFLDataFormat *dataIn,
SFLDataFormat *dataOut, int inputFreq,
int outputFreq, int nbSamples)
{ {
double sampleFactor = (double) outputFreq / inputFreq; double sampleFactor = (double) outputFreq / inputFreq;
if (sampleFactor == 1.0) if (sampleFactor == 1.0)
return; return;
unsigned int outSamples = nbSamples * sampleFactor; const int outSamples = nbSamples * sampleFactor;
unsigned int maxSamples = outSamples; const unsigned int maxSamples = std::max(outSamples, nbSamples);
if (maxSamples < (unsigned int)nbSamples)
maxSamples = nbSamples;
if (maxSamples > samples_) { if (maxSamples > samples_) {
/* grow buffer if needed */ /* grow buffer if needed */
......
...@@ -58,7 +58,7 @@ class SamplerateConverter { ...@@ -58,7 +58,7 @@ class SamplerateConverter {
* @param SamplerateConverter2 The desired sample rate * @param SamplerateConverter2 The desired sample rate
* @param nbSamples The number of samples to process * @param nbSamples The number of samples to process
*/ */
void resample(SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples); void resample(SFLDataFormat* dataIn , SFLDataFormat* dataOut , int oldrate, int newrate, int nbSamples);
/** /**
* Convert short table to floats for audio processing * Convert short table to floats for audio processing
......
...@@ -66,11 +66,11 @@ RawFile::RawFile(const std::string& name, sfl::AudioCodec* codec, unsigned int s ...@@ -66,11 +66,11 @@ RawFile::RawFile(const std::string& name, sfl::AudioCodec* codec, unsigned int s
file.read(fileBuffer,length); file.read(fileBuffer,length);
file.close(); file.close();
unsigned int frameSize = audioCodec_->getFrameSize(); const unsigned int frameSize = audioCodec_->getFrameSize();
unsigned int bitrate = audioCodec_->getBitRate() * 1000 / 8; const unsigned int bitrate = audioCodec_->getBitRate() * 1000 / 8;
unsigned int audioRate = audioCodec_->getClockRate(); const unsigned int audioRate = audioCodec_->getClockRate();
unsigned int encFrameSize = frameSize * bitrate / audioRate; const unsigned int encFrameSize = frameSize * bitrate / audioRate;
unsigned int decodedSize = length * (frameSize / encFrameSize); const unsigned int decodedSize = length * (frameSize / encFrameSize);
SFLDataFormat *monoBuffer = new SFLDataFormat[decodedSize]; SFLDataFormat *monoBuffer = new SFLDataFormat[decodedSize];
SFLDataFormat *bufpos = monoBuffer; SFLDataFormat *bufpos = monoBuffer;
...@@ -115,9 +115,9 @@ RawFile::RawFile(const std::string& name, sfl::AudioCodec* codec, unsigned int s ...@@ -115,9 +115,9 @@ RawFile::RawFile(const std::string& name, sfl::AudioCodec* codec, unsigned int s
} }
WaveFile::WaveFile(const std::string& fileName, unsigned int audioSamplingRate) WaveFile::WaveFile(const std::string& fileName, int newRate)
{ {
std::fstream fs(fileName.c_str(), std::ios_base::in); const std::fstream fs(fileName.c_str(), std::ios_base::in);
if (!fs) if (!fs)
throw AudioFileException("File " + fileName + " doesn't exist"); throw AudioFileException("File " + fileName + " doesn't exist");
...@@ -127,49 +127,48 @@ WaveFile::WaveFile(const std::string& fileName, unsigned int audioSamplingRate) ...@@ -127,49 +127,48 @@ WaveFile::WaveFile(const std::string& fileName, unsigned int audioSamplingRate)
fileStream.open(fileName.c_str(), std::ios::in | std::ios::binary); fileStream.open(fileName.c_str(), std::ios::in | std::ios::binary);
char riff[4] = { 0, 0, 0, 0 }; char riff[4] = { 0, 0, 0, 0 };
fileStream.read(riff, 4); fileStream.read(riff, sizeof riff / sizeof riff[0]);
if (strncmp("RIFF", riff, 4) != 0) if (strncmp("RIFF", riff, sizeof riff / sizeof riff[0]) != 0)
throw AudioFileException("File is not of RIFF format"); throw AudioFileException("File is not of RIFF format");
char fmt[4] = { 0, 0, 0, 0 }; char fmt[4] = { 0, 0, 0, 0 };
int maxIteration = 10; int maxIteration = 10;
while (maxIteration-- && strncmp("fmt ", fmt, 4)) while (maxIteration-- and strncmp("fmt ", fmt, sizeof fmt / sizeof fmt[0]))
fileStream.read(fmt, 4); fileStream.read(fmt, sizeof fmt / sizeof fmt[0]);
if (maxIteration == 0) if (maxIteration == 0)
throw AudioFileException("Could not find \"fmt \" chunk"); throw AudioFileException("Could not find \"fmt \" chunk");
SINT32 chunk_size; // fmt chunk size SINT32 chunkSize; // fmt chunk size
fileStream.read(reinterpret_cast<char *>(&chunkSize), sizeof chunkSize); // Read fmt chunk size.
unsigned short formatTag; // data compression tag unsigned short formatTag; // data compression tag
fileStream.read(reinterpret_cast<char *>(&formatTag), sizeof formatTag);
fileStream.read(reinterpret_cast<char*>(&chunk_size), 4); // Read fmt chunk size.
fileStream.read(reinterpret_cast<char*>(&formatTag), 2);
if (formatTag != 1) // PCM = 1, FLOAT = 3 if (formatTag != 1) // PCM = 1, FLOAT = 3
throw AudioFileException("File contains an unsupported data format type"); throw AudioFileException("File contains an unsupported data format type");
// Get number of channels from the header. // Get number of channels from the header.
SINT16 chan; SINT16 chan;
fileStream.read((char*) &chan, 2); fileStream.read(reinterpret_cast<char *>(&chan), sizeof chan);
if (chan > 2) if (chan > 2)
throw AudioFileException("WaveFile: unsupported number of channels"); throw AudioFileException("WaveFile: unsupported number of channels");
// Get file sample rate from the header. // Get file sample rate from the header.
SINT32 srate; SINT32 fileRate;
fileStream.read((char*) &srate, 4); fileStream.read(reinterpret_cast<char *>(&fileRate), sizeof fileRate);
SINT32 avgb; SINT32 avgb;
fileStream.read((char*) &avgb, 4); fileStream.read(reinterpret_cast<char *>(&avgb), sizeof avgb);
SINT16 blockal; SINT16 blockal;
fileStream.read((char*) &blockal, 2); fileStream.read(reinterpret_cast<char *>(&blockal), sizeof blockal);
// Determine the data type // Determine the data type
SINT16 dt; SINT16 dt;
fileStream.read((char*) &dt, 2); fileStream.read(reinterpret_cast<char *>(&dt), sizeof dt);
if (dt != 8 && dt != 16 && dt != 32) if (dt != 8 && dt != 16 && dt != 32)
throw AudioFileException("File's bits per sample with is not supported"); throw AudioFileException("File's bits per sample with is not supported");
...@@ -178,46 +177,45 @@ WaveFile::WaveFile(const std::string& fileName, unsigned int audioSamplingRate) ...@@ -178,46 +177,45 @@ WaveFile::WaveFile(const std::string& fileName, unsigned int audioSamplingRate)
char data[4] = { 0, 0, 0, 0 }; char data[4] = { 0, 0, 0, 0 };
maxIteration = 10; maxIteration = 10;
while (maxIteration-- && strncmp("data", data, 4)) while (maxIteration-- && strncmp("data", data, sizeof data / sizeof data[0]))
fileStream.read(data, 4); fileStream.read(data, sizeof data / sizeof data[0]);
// Samplerate converter initialized with 88200 sample long // Samplerate converter initialized with 88200 sample long
int converterSamples = ((unsigned int)srate > audioSamplingRate) ? srate : audioSamplingRate; SamplerateConverter converter(std::max(fileRate, newRate));
SamplerateConverter converter_(converterSamples);
// Get length of data from the header. // Get length of data from the header.
SINT32 bytes; SINT32 bytes;
fileStream.read((char*) &bytes, 4); fileStream.read(reinterpret_cast<char *>(&bytes), sizeof bytes);
unsigned long nbSamples = 8 * bytes / dt / chan; // sample frames
DEBUG("WaveFile: frame size %ld, data size %d align %d rate %d avgbyte %d chunk size %d dt %d", // sample frames, should not be longer than a minute
nbSamples, bytes, blockal, srate, avgb, chunk_size, dt); int nbSamples = std::min(60 * fileRate, 8 * bytes / dt / chan);
// Should not be longer than a minute DEBUG("WaveFile: frame size %ld, data size %d align %d rate %d avgbyte %d "
if (nbSamples > static_cast<unsigned int>(60 * srate)) "chunk size %d dt %d", nbSamples, bytes, blockal, fileRate, avgb,
nbSamples = 60 * srate; chunkSize, dt);
SFLDataFormat *tempBuffer = new SFLDataFormat[nbSamples]; size_ = nbSamples;
SFLDataFormat *tempBuffer = new SFLDataFormat[size_];
fileStream.read(reinterpret_cast<char *>(tempBuffer), nbSamples * sizeof(SFLDataFormat)); fileStream.read(reinterpret_cast<char *>(tempBuffer),
nbSamples * sizeof(SFLDataFormat));
// mix two channels together if stereo // mix two channels together if stereo
if (chan == 2) { if (chan == 2) {
for (unsigned int i = 0; i < nbSamples - 1; i += 2) for (int i = 0, j = 0; i < nbSamples - 1; i += 2, ++j)
tempBuffer[static_cast<size_t>(i * 0.5)] = (tempBuffer[i] + tempBuffer[i + 1]) * 0.5; tempBuffer[j] = (tempBuffer[i] + tempBuffer[i + 1]) * 0.5;
nbSamples *= 0.5; nbSamples *= 0.5;
} }
if ((unsigned int) srate != audioSamplingRate) { if (fileRate != newRate) {
int outSamples = ((float) nbSamples * ((float) audioSamplingRate / (float) srate)); const float ratio = newRate / (float) fileRate;
buffer_ = new SFLDataFormat[outSamples]; const int outSamples = ceil(nbSamples * ratio);
converter_.resample(tempBuffer, buffer_, srate, audioSamplingRate, nbSamples); size_ = outSamples;
buffer_ = new SFLDataFormat[size_];
converter.resample(tempBuffer, buffer_, fileRate, newRate, nbSamples);
delete [] tempBuffer; delete [] tempBuffer;
} else } else
buffer_ = tempBuffer; buffer_ = tempBuffer;
size_ = nbSamples; sampleRate_ = newRate;
sampleRate_ = audioSamplingRate;
} }
...@@ -83,7 +83,7 @@ class WaveFile : public AudioFile { ...@@ -83,7 +83,7 @@ class WaveFile : public AudioFile {
* @param filename The absolute path to the file * @param filename The absolute path to the file
* @param sampleRate The sample rate to read it * @param sampleRate The sample rate to read it
*/ */
WaveFile(const std::string&, unsigned int); WaveFile(const std::string&, int);
}; };
#endif // __AUDIOFILE_H__ #endif // __AUDIOFILE_H__
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment