Show error message when loading an invalid sample file (#6286)
This commit is contained in:
committed by
GitHub
parent
21fb430c76
commit
07229b6404
@@ -77,7 +77,7 @@ public:
|
||||
|
||||
public slots:
|
||||
void setSampleBuffer( lmms::SampleBuffer* sb );
|
||||
void setSampleFile( const QString & _sf );
|
||||
void setSampleFile( const QString & sf );
|
||||
void updateLength();
|
||||
void toggleRecord();
|
||||
void playbackPositionChanged();
|
||||
|
||||
@@ -247,7 +247,15 @@ void SampleBuffer::update(bool keepSettings)
|
||||
const int fileSizeMax = 300; // MB
|
||||
const int sampleLengthMax = 90; // Minutes
|
||||
|
||||
bool fileLoadError = false;
|
||||
enum class FileLoadError
|
||||
{
|
||||
None,
|
||||
ReadPermissionDenied,
|
||||
TooLarge,
|
||||
Invalid
|
||||
};
|
||||
FileLoadError fileLoadError = FileLoadError::None;
|
||||
|
||||
if (m_audioFile.isEmpty() && m_origData != nullptr && m_origFrames > 0)
|
||||
{
|
||||
// TODO: reverse- and amplification-property is not covered
|
||||
@@ -271,31 +279,40 @@ void SampleBuffer::update(bool keepSettings)
|
||||
m_frames = 0;
|
||||
|
||||
const QFileInfo fileInfo(file);
|
||||
if (fileInfo.size() > fileSizeMax * 1024 * 1024)
|
||||
if (!fileInfo.isReadable())
|
||||
{
|
||||
fileLoadError = true;
|
||||
fileLoadError = FileLoadError::ReadPermissionDenied;
|
||||
}
|
||||
else if (fileInfo.size() > fileSizeMax * 1024 * 1024)
|
||||
{
|
||||
fileLoadError = FileLoadError::TooLarge;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use QFile to handle unicode file names on Windows
|
||||
QFile f(file);
|
||||
SNDFILE * sndFile;
|
||||
SNDFILE * sndFile = nullptr;
|
||||
SF_INFO sfInfo;
|
||||
sfInfo.format = 0;
|
||||
|
||||
if (f.open(QIODevice::ReadOnly) && (sndFile = sf_open_fd(f.handle(), SFM_READ, &sfInfo, false)))
|
||||
{
|
||||
f_cnt_t frames = sfInfo.frames;
|
||||
int rate = sfInfo.samplerate;
|
||||
if (frames / rate > sampleLengthMax * 60)
|
||||
{
|
||||
fileLoadError = true;
|
||||
fileLoadError = FileLoadError::TooLarge;
|
||||
}
|
||||
sf_close(sndFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileLoadError = FileLoadError::Invalid;
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
|
||||
if (!fileLoadError)
|
||||
if (fileLoadError == FileLoadError::None)
|
||||
{
|
||||
#ifdef LMMS_HAVE_OGGVORBIS
|
||||
// workaround for a bug in libsndfile or our libsndfile decoder
|
||||
@@ -322,7 +339,7 @@ void SampleBuffer::update(bool keepSettings)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_frames == 0 || fileLoadError) // if still no frames, bail
|
||||
if (m_frames == 0 || fileLoadError != FileLoadError::None) // if still no frames, bail
|
||||
{
|
||||
// sample couldn't be decoded, create buffer containing
|
||||
// one sample-frame
|
||||
@@ -363,16 +380,35 @@ void SampleBuffer::update(bool keepSettings)
|
||||
}
|
||||
Oscillator::generateAntiAliasUserWaveTable(this);
|
||||
|
||||
if (fileLoadError)
|
||||
if (fileLoadError != FileLoadError::None)
|
||||
{
|
||||
QString title = tr("Fail to open file");
|
||||
QString message = tr("Audio files are limited to %1 MB "
|
||||
"in size and %2 minutes of playing time"
|
||||
).arg(fileSizeMax).arg(sampleLengthMax);
|
||||
QString message;
|
||||
|
||||
switch (fileLoadError)
|
||||
{
|
||||
case FileLoadError::None:
|
||||
// present just to avoid a compiler warning
|
||||
break;
|
||||
|
||||
case FileLoadError::ReadPermissionDenied:
|
||||
message = tr("Read permission denied");
|
||||
break;
|
||||
|
||||
case FileLoadError::TooLarge:
|
||||
message = tr("Audio files are limited to %1 MB "
|
||||
"in size and %2 minutes of playing time"
|
||||
).arg(fileSizeMax).arg(sampleLengthMax);
|
||||
break;
|
||||
|
||||
case FileLoadError::Invalid:
|
||||
message = tr("Invalid audio file");
|
||||
break;
|
||||
}
|
||||
|
||||
if (gui::getGUI() != nullptr)
|
||||
{
|
||||
QMessageBox::information(nullptr,
|
||||
title, message, QMessageBox::Ok);
|
||||
QMessageBox::information(nullptr, title, message, QMessageBox::Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -143,23 +143,26 @@ void SampleClip::setSampleBuffer( SampleBuffer* sb )
|
||||
|
||||
|
||||
|
||||
void SampleClip::setSampleFile( const QString & _sf )
|
||||
void SampleClip::setSampleFile(const QString & sf)
|
||||
{
|
||||
int length;
|
||||
if ( _sf.isEmpty() )
|
||||
{ //When creating an empty sample clip make it a bar long
|
||||
float nom = Engine::getSong()->getTimeSigModel().getNumerator();
|
||||
float den = Engine::getSong()->getTimeSigModel().getDenominator();
|
||||
length = DefaultTicksPerBar * ( nom / den );
|
||||
}
|
||||
else
|
||||
{ //Otherwise set it to the sample's length
|
||||
m_sampleBuffer->setAudioFile( _sf );
|
||||
int length = 0;
|
||||
|
||||
if (!sf.isEmpty())
|
||||
{
|
||||
m_sampleBuffer->setAudioFile(sf);
|
||||
length = sampleLength();
|
||||
}
|
||||
changeLength(length);
|
||||
|
||||
setStartTimeOffset( 0 );
|
||||
if (length == 0)
|
||||
{
|
||||
//If there is no sample, make the clip a bar long
|
||||
float nom = Engine::getSong()->getTimeSigModel().getNumerator();
|
||||
float den = Engine::getSong()->getTimeSigModel().getDenominator();
|
||||
length = DefaultTicksPerBar * (nom / den);
|
||||
}
|
||||
|
||||
changeLength(length);
|
||||
setStartTimeOffset(0);
|
||||
|
||||
emit sampleChanged();
|
||||
emit playbackPositionChanged();
|
||||
|
||||
Reference in New Issue
Block a user