changeset 290:92e8dbde73cd

* Revert revision 713. We do like QStrings after all.
author Chris Cannam
date Fri, 24 Aug 2007 11:41:48 +0000
parents 3020904de772
children 42e6c8360df1
files data/fft/FFTFileCache.cpp data/fileio/AudioFileReader.cpp data/fileio/AudioFileReader.h data/fileio/AudioFileReaderFactory.cpp data/fileio/AudioFileReaderFactory.h data/fileio/CodedAudioFileReader.cpp data/fileio/CodedAudioFileReader.h data/fileio/FileFinder.cpp data/fileio/MP3FileReader.cpp data/fileio/MP3FileReader.h data/fileio/OggVorbisFileReader.cpp data/fileio/OggVorbisFileReader.h data/fileio/QuickTimeFileReader.cpp data/fileio/QuickTimeFileReader.h data/fileio/WavFileReader.cpp data/fileio/WavFileReader.h data/model/Model.h data/model/WaveFileModel.cpp data/model/WritableWaveFileModel.cpp
diffstat 19 files changed, 128 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- a/data/fft/FFTFileCache.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fft/FFTFileCache.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -277,7 +277,8 @@
             float mag = sqrtf(real[y] * real[y] + imag[y] * imag[y]);
             if (mag > factor) factor = mag;
             ((float *)m_writebuf)[y * 2] = mag;
-            ((float *)m_writebuf)[y * 2 + 1] = princargf(atan2f(imag[y], real[y]));
+            float phase = princargf(atan2f(imag[y], real[y]));
+            ((float *)m_writebuf)[y * 2 + 1] = phase;
         }
         break;
     }
--- a/data/fileio/AudioFileReader.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/AudioFileReader.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -15,19 +15,3 @@
 
 #include "AudioFileReader.h"
 
-void
-AudioFileReader::setError(std::string text, std::string arg)
-{
-    if (arg == "") m_error = text;
-    else m_error = text + ": " + arg;
-}
-
-void
-AudioFileReader::setError(std::string text, int arg)
-{
-    char *buf = new char(text.length() + 100);
-    sprintf(buf, "%s: code %d", text.c_str(), arg);
-    m_error = buf;
-    delete[] buf;
-}
-
--- a/data/fileio/AudioFileReader.h	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/AudioFileReader.h	Fri Aug 24 11:41:48 2007 +0000
@@ -16,10 +16,8 @@
 #ifndef _AUDIO_FILE_READER_H_
 #define _AUDIO_FILE_READER_H_
 
-#include <QObject>
-
-#include <string>
-#include <vector>
+#include <QString>
+#include "model/Model.h" // for SampleBlock
 
 class AudioFileReader : public QObject
 {
@@ -28,11 +26,9 @@
 public:
     virtual ~AudioFileReader() { }
 
-    typedef std::vector<float> SampleBlock;
-
     bool isOK() const { return (m_channelCount > 0); }
 
-    virtual std::string getError() const { return m_error; }
+    virtual QString getError() const { return ""; }
 
     size_t getFrameCount() const { return m_frameCount; }
     size_t getChannelCount() const { return m_channelCount; }
@@ -43,7 +39,7 @@
      * may be implemented by subclasses that support file tagging.
      * This is not the same thing as the file name.
      */
-    virtual std::string getTitle() const { return ""; }
+    virtual QString getTitle() const { return ""; }
 
     /** 
      * The subclass implementations of this function must be
@@ -66,10 +62,6 @@
     size_t m_frameCount;
     size_t m_channelCount;
     size_t m_sampleRate;
-
-    std::string m_error;
-    void setError(std::string text, std::string arg = "");
-    void setError(std::string text, int arg);
 };
 
 #endif
--- a/data/fileio/AudioFileReaderFactory.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/AudioFileReaderFactory.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -24,10 +24,10 @@
 #include <QFileInfo>
 #include <iostream>
 
-std::string
+QString
 AudioFileReaderFactory::getKnownExtensions()
 {
-    std::set<std::string> extensions;
+    std::set<QString> extensions;
 
     WavFileReader::getSupportedExtensions(extensions);
 #ifdef HAVE_MAD
@@ -42,8 +42,8 @@
     QuickTimeFileReader::getSupportedExtensions(extensions);
 #endif
 
-    std::string rv;
-    for (std::set<std::string>::const_iterator i = extensions.begin();
+    QString rv;
+    for (std::set<QString>::const_iterator i = extensions.begin();
          i != extensions.end(); ++i) {
         if (i != extensions.begin()) rv += " ";
         rv += "*." + *i;
@@ -53,9 +53,9 @@
 }
 
 AudioFileReader *
-AudioFileReaderFactory::createReader(std::string path)
+AudioFileReaderFactory::createReader(QString path)
 {
-    std::string err;
+    QString err;
 
     AudioFileReader *reader = 0;
 
@@ -63,16 +63,8 @@
     // extension.  If we can't identify one or it fails to load the
     // file, fall back to trying all readers in no particular order.
 
-    std::string ext;
-    std::string::size_type idx = path.rfind('.');
-    if (idx != std::string::npos) {
-        ext = path.substr(idx + 1);
-        for (size_t i = 0; i < ext.length(); ++i) {
-            ext[i] = std::tolower(ext[i]);
-        }
-    }
-
-    std::set<std::string> extensions;
+    QString ext = QFileInfo(path).suffix().toLower();
+    std::set<QString> extensions;
 
     WavFileReader::getSupportedExtensions(extensions);
     if (extensions.find(ext) != extensions.end()) {
@@ -124,11 +116,11 @@
         if (reader->isOK()) return reader;
         if (reader->getError() != "") {
             std::cerr << "AudioFileReaderFactory: Preferred reader for "
-                      << "extension \"" << ext << "\" failed: \""
-                      << reader->getError() << "\"" << std::endl;
+                      << "extension \"" << ext.toStdString() << "\" failed: \""
+                      << reader->getError().toStdString() << "\"" << std::endl;
         } else {
             std::cerr << "AudioFileReaderFactory: Preferred reader for "
-                      << "extension \"" << ext << "\" failed"
+                      << "extension \"" << ext.toStdString() << "\" failed"
                       << std::endl;
         }            
         delete reader;
@@ -139,7 +131,7 @@
     if (reader->isOK()) return reader;
     if (reader->getError() != "") {
 	std::cerr << "AudioFileReaderFactory: WAV file reader error: \""
-                  << reader->getError() << "\"" << std::endl;
+                  << reader->getError().toStdString() << "\"" << std::endl;
     } else {
 	std::cerr << "AudioFileReaderFactory: WAV file reader failed"
                   << std::endl;
@@ -155,7 +147,7 @@
     if (reader->isOK()) return reader;
     if (reader->getError() != "") {
 	std::cerr << "AudioFileReaderFactory: Ogg file reader error: \""
-                  << reader->getError() << "\"" << std::endl;
+                  << reader->getError().toStdString() << "\"" << std::endl;
     } else {
 	std::cerr << "AudioFileReaderFactory: Ogg file reader failed"
                   << std::endl;
@@ -172,7 +164,7 @@
     if (reader->isOK()) return reader;
     if (reader->getError() != "") {
 	std::cerr << "AudioFileReaderFactory: MP3 file reader error: \""
-                  << reader->getError() << "\"" << std::endl;
+                  << reader->getError().toStdString() << "\"" << std::endl;
     } else {
 	std::cerr << "AudioFileReaderFactory: MP3 file reader failed"
                   << std::endl;
@@ -188,7 +180,7 @@
     if (reader->isOK()) return reader;
     if (reader->getError() != "") {
 	std::cerr << "AudioFileReaderFactory: QuickTime file reader error: \""
-                  << reader->getError() << "\"" << std::endl;
+                  << reader->getError().toStdString() << "\"" << std::endl;
     } else {
 	std::cerr << "AudioFileReaderFactory: QuickTime file reader failed"
                   << std::endl;
--- a/data/fileio/AudioFileReaderFactory.h	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/AudioFileReaderFactory.h	Fri Aug 24 11:41:48 2007 +0000
@@ -16,7 +16,7 @@
 #ifndef _AUDIO_FILE_READER_FACTORY_H_
 #define _AUDIO_FILE_READER_FACTORY_H_
 
-#include <string>
+#include <QString>
 
 class AudioFileReader;
 
@@ -28,7 +28,7 @@
      * in a format suitable for use with QFileDialog.  For example,
      * "*.wav *.aiff *.ogg".
      */
-    static std::string getKnownExtensions();
+    static QString getKnownExtensions();
 
     /**
      * Return an audio file reader initialised to the file at the
@@ -36,7 +36,7 @@
      * available or the file cannot be opened.
      * Caller owns the returned object and must delete it after use.
      */
-    static AudioFileReader *createReader(std::string path);
+    static AudioFileReader *createReader(QString path);
 };
 
 #endif
--- a/data/fileio/CodedAudioFileReader.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/CodedAudioFileReader.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -44,8 +44,8 @@
     if (m_cacheWriteBuffer) delete[] m_cacheWriteBuffer;
 
     if (m_cacheFileName != "") {
-        if (!QFile(m_cacheFileName.c_str()).remove()) {
-            std::cerr << "WARNING: CodedAudioFileReader::~CodedAudioFileReader: Failed to delete cache file \"" << m_cacheFileName << "\"" << std::endl;
+        if (!QFile(m_cacheFileName).remove()) {
+            std::cerr << "WARNING: CodedAudioFileReader::~CodedAudioFileReader: Failed to delete cache file \"" << m_cacheFileName.toStdString() << "\"" << std::endl;
         }
     }
 }
@@ -63,14 +63,14 @@
         try {
             QDir dir(TempDirectory::getInstance()->getPath());
             m_cacheFileName = dir.filePath(QString("decoded_%1.wav")
-                                           .arg((intptr_t)this)).toStdString();
+                                           .arg((intptr_t)this));
 
             SF_INFO fileInfo;
             fileInfo.samplerate = m_sampleRate;
             fileInfo.channels = m_channelCount;
             fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
     
-            m_cacheFileWritePtr = sf_open(m_cacheFileName.c_str(),
+            m_cacheFileWritePtr = sf_open(m_cacheFileName.toLocal8Bit(),
                                           SFM_WRITE, &fileInfo);
 
             if (m_cacheFileWritePtr) {
@@ -83,14 +83,14 @@
                 m_cacheFileReader = new WavFileReader(m_cacheFileName);
 
                 if (!m_cacheFileReader->isOK()) {
-                    std::cerr << "ERROR: CodedAudioFileReader::initialiseDecodeCache: Failed to construct WAV file reader for temporary file: " << m_cacheFileReader->getError() << std::endl;
+                    std::cerr << "ERROR: CodedAudioFileReader::initialiseDecodeCache: Failed to construct WAV file reader for temporary file: " << m_cacheFileReader->getError().toStdString() << std::endl;
                     delete m_cacheFileReader;
                     m_cacheFileReader = 0;
                     m_cacheMode = CacheInMemory;
                     sf_close(m_cacheFileWritePtr);
                 }
             } else {
-                std::cerr << "CodedAudioFileReader::initialiseDecodeCache: failed to open cache file \"" << m_cacheFileName << "\" (" << m_channelCount << " channels, sample rate " << m_sampleRate << " for writing, falling back to in-memory cache" << std::endl;
+                std::cerr << "CodedAudioFileReader::initialiseDecodeCache: failed to open cache file \"" << m_cacheFileName.toStdString() << "\" (" << m_channelCount << " channels, sample rate " << m_sampleRate << " for writing, falling back to in-memory cache" << std::endl;
                 m_cacheMode = CacheInMemory;
             }
 
@@ -181,7 +181,7 @@
         m_cacheFileReader = new WavFileReader(m_cacheFileName);
 
         if (!m_cacheFileReader->isOK()) {
-            std::cerr << "ERROR: CodedAudioFileReader::finishDecodeCache: Failed to construct WAV file reader for temporary file: " << m_cacheFileReader->getError() << std::endl;
+            std::cerr << "ERROR: CodedAudioFileReader::finishDecodeCache: Failed to construct WAV file reader for temporary file: " << m_cacheFileReader->getError().toStdString() << std::endl;
             delete m_cacheFileReader;
             m_cacheFileReader = 0;
         }*/
--- a/data/fileio/CodedAudioFileReader.h	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/CodedAudioFileReader.h	Fri Aug 24 11:41:48 2007 +0000
@@ -49,7 +49,7 @@
     SampleBlock m_data;
     bool m_initialised;
 
-    std::string m_cacheFileName;
+    QString m_cacheFileName;
     SNDFILE *m_cacheFileWritePtr;
     WavFileReader *m_cacheFileReader;
     float *m_cacheWriteBuffer;
--- a/data/fileio/FileFinder.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/FileFinder.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -68,7 +68,7 @@
         settingsKey = "audiopath";
         title = "Select an audio file";
         filter = tr("Audio files (%1)\nAll files (*.*)")
-            .arg(AudioFileReaderFactory::getKnownExtensions().c_str());
+            .arg(AudioFileReaderFactory::getKnownExtensions());
         break;
 
     case LayerFile:
@@ -79,7 +79,7 @@
     case SessionOrAudioFile:
         settingsKey = "lastpath";
         filter = tr("All supported files (*.sv %1)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nAll files (*.*)")
-            .arg(AudioFileReaderFactory::getKnownExtensions().c_str());
+            .arg(AudioFileReaderFactory::getKnownExtensions());
         break;
 
     case ImageFile:
@@ -90,7 +90,7 @@
     case AnyFile:
         settingsKey = "lastpath";
         filter = tr("All supported files (*.sv %1 %2)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nLayer files (%2)\nAll files (*.*)")
-            .arg(AudioFileReaderFactory::getKnownExtensions().c_str())
+            .arg(AudioFileReaderFactory::getKnownExtensions())
             .arg(DataFileReaderFactory::getKnownExtensions());
         break;
     };
--- a/data/fileio/MP3FileReader.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/MP3FileReader.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -34,7 +34,7 @@
 #include <QFileInfo>
 #include <QProgressDialog>
 
-MP3FileReader::MP3FileReader(std::string path, DecodeMode decodeMode, CacheMode mode) :
+MP3FileReader::MP3FileReader(QString path, DecodeMode decodeMode, CacheMode mode) :
     CodedAudioFileReader(mode),
     m_path(path),
     m_decodeThread(0)
@@ -52,20 +52,20 @@
     m_progress = 0;
 
     struct stat stat;
-    if (::stat(path.c_str(), &stat) == -1 || stat.st_size == 0) {
-        setError("File does not exist", path);
+    if (::stat(path.toLocal8Bit().data(), &stat) == -1 || stat.st_size == 0) {
+	m_error = QString("File %1 does not exist.").arg(path);
 	return;
     }
 
     m_fileSize = stat.st_size;
 
     int fd = -1;
-    if ((fd = ::open(path.c_str(), O_RDONLY
+    if ((fd = ::open(path.toLocal8Bit().data(), O_RDONLY
 #ifdef _WIN32
                      | O_BINARY
 #endif
                      , 0)) < 0) {
-	setError("Failed to open file for reading", path);
+	m_error = QString("Failed to open file %1 for reading.").arg(path);
 	return;
     }	
 
@@ -74,7 +74,7 @@
     try {
         m_filebuffer = new unsigned char[m_fileSize];
     } catch (...) {
-        setError("Out of memory");
+        m_error = QString("Out of memory");
         ::close(fd);
 	return;
     }
@@ -84,7 +84,8 @@
     while (offset < m_fileSize) {
         sz = ::read(fd, m_filebuffer + offset, m_fileSize - offset);
         if (sz < 0) {
-            setError("Read error", path);
+            m_error = QString("Read error for file %1 (after %2 bytes)")
+                .arg(path).arg(offset);
             delete[] m_filebuffer;
             ::close(fd);
             return;
@@ -104,12 +105,12 @@
     if (decodeMode == DecodeAtOnce) {
 
 	m_progress = new QProgressDialog
-	    (QObject::tr("Decoding %1...").arg(QFileInfo(path.c_str()).fileName()),
+	    (QObject::tr("Decoding %1...").arg(QFileInfo(path).fileName()),
 	     QObject::tr("Stop"), 0, 100);
 	m_progress->hide();
 
         if (!decode(m_filebuffer, m_fileSize)) {
-            setError("Failed to decode file", path);
+            m_error = QString("Failed to decode file %1.").arg(path);
         }
         
         delete[] m_filebuffer;
@@ -147,7 +148,7 @@
 
 #ifdef HAVE_ID3TAG
 
-    id3_file *file = id3_file_open(m_path.c_str(),
+    id3_file *file = id3_file_open(m_path.toLocal8Bit().data(),
                                    ID3_FILE_MODE_READONLY);
     if (!file) return;
 
@@ -203,7 +204,7 @@
         return;
     }
         
-    m_title = (const char *)u8str;
+    m_title = QString::fromUtf8((const char *)u8str);
     free(u8str);
     id3_file_close(file);
 
@@ -220,7 +221,7 @@
 MP3FileReader::DecodeThread::run()
 {
     if (!m_reader->decode(m_reader->m_filebuffer, m_reader->m_fileSize)) {
-        m_reader->setError("Failed to decode file", m_reader->m_path);
+        m_reader->m_error = QString("Failed to decode file %1.").arg(m_reader->m_path);
     }
 
     delete[] m_reader->m_filebuffer;
@@ -360,7 +361,7 @@
 }
 
 void
-MP3FileReader::getSupportedExtensions(std::set<std::string> &extensions)
+MP3FileReader::getSupportedExtensions(std::set<QString> &extensions)
 {
     extensions.insert("mp3");
 }
--- a/data/fileio/MP3FileReader.h	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/MP3FileReader.h	Fri Aug 24 11:41:48 2007 +0000
@@ -35,12 +35,14 @@
         DecodeThreaded // decode in a background thread after construction
     };
 
-    MP3FileReader(std::string path, DecodeMode decodeMode, CacheMode cacheMode);
+    MP3FileReader(QString path, DecodeMode decodeMode, CacheMode cacheMode);
     virtual ~MP3FileReader();
 
-    virtual std::string getTitle() const { return m_title; }
+    virtual QString getError() const { return m_error; }
+
+    virtual QString getTitle() const { return m_title; }
     
-    static void getSupportedExtensions(std::set<std::string> &extensions);
+    static void getSupportedExtensions(std::set<QString> &extensions);
     
     virtual int getDecodeCompletion() const { return m_completion; }
 
@@ -49,8 +51,9 @@
     }
 
 protected:
-    std::string m_path;
-    std::string m_title;
+    QString m_path;
+    QString m_error;
+    QString m_title;
     size_t m_fileSize;
     double m_bitrateNum;
     size_t m_bitrateDenom;
--- a/data/fileio/OggVorbisFileReader.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/OggVorbisFileReader.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -32,7 +32,7 @@
 
 static int instances = 0;
 
-OggVorbisFileReader::OggVorbisFileReader(std::string path,
+OggVorbisFileReader::OggVorbisFileReader(QString path,
                                          DecodeMode decodeMode,
                                          CacheMode mode) :
     CodedAudioFileReader(mode),
@@ -49,15 +49,15 @@
     m_channelCount = 0;
     m_sampleRate = 0;
 
-    std::cerr << "OggVorbisFileReader::OggVorbisFileReader(" << path << "): now have " << (++instances) << " instances" << std::endl;
+    std::cerr << "OggVorbisFileReader::OggVorbisFileReader(" << path.toLocal8Bit().data() << "): now have " << (++instances) << " instances" << std::endl;
 
     Profiler profiler("OggVorbisFileReader::OggVorbisFileReader", true);
 
-    QFileInfo info(path.c_str());
+    QFileInfo info(path);
     m_fileSize = info.size();
 
-    if (!(m_oggz = oggz_open(path.c_str(), OGGZ_READ))) {
-        setError("File is not an OGG file", path);
+    if (!(m_oggz = oggz_open(path.toLocal8Bit().data(), OGGZ_READ))) {
+	m_error = QString("File %1 is not an OGG file.").arg(path);
 	return;
     }
 
@@ -70,7 +70,7 @@
     if (decodeMode == DecodeAtOnce) {
 
 	m_progress = new QProgressDialog
-	    (QObject::tr("Decoding %1...").arg(QFileInfo(path.c_str()).fileName()),
+	    (QObject::tr("Decoding %1...").arg(QFileInfo(path).fileName()),
 	     QObject::tr("Stop"), 0, 100);
 	m_progress->hide();
 
@@ -100,7 +100,7 @@
 
 OggVorbisFileReader::~OggVorbisFileReader()
 {
-    std::cerr << "OggVorbisFileReader::~OggVorbisFileReader(" << m_path << "): now have " << (--instances) << " instances" << std::endl;
+    std::cerr << "OggVorbisFileReader::~OggVorbisFileReader(" << m_path.toLocal8Bit().data() << "): now have " << (--instances) << " instances" << std::endl;
     if (m_decodeThread) {
         m_cancelled = true;
         m_decodeThread->wait();
@@ -166,7 +166,7 @@
         const FishSoundComment *comment = fish_sound_comment_first_byname
             (fs, "TITLE");
         if (comment && comment->value) {
-            reader->m_title = comment->value;
+            reader->m_title = QString::fromUtf8(comment->value);
         }
         reader->m_commentsRead = true;
     }
@@ -198,7 +198,7 @@
 }
 
 void
-OggVorbisFileReader::getSupportedExtensions(std::set<std::string> &extensions)
+OggVorbisFileReader::getSupportedExtensions(std::set<QString> &extensions)
 {
     extensions.insert("ogg");
 }
--- a/data/fileio/OggVorbisFileReader.h	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/OggVorbisFileReader.h	Fri Aug 24 11:41:48 2007 +0000
@@ -37,13 +37,15 @@
         DecodeThreaded // decode in a background thread after construction
     };
 
-    OggVorbisFileReader(std::string path, DecodeMode decodeMode,
+    OggVorbisFileReader(QString path, DecodeMode decodeMode,
                         CacheMode cacheMode);
     virtual ~OggVorbisFileReader();
 
-    virtual std::string getTitle() const { return m_title; }
+    virtual QString getError() const { return m_error; }
+
+    virtual QString getTitle() const { return m_title; }
     
-    static void getSupportedExtensions(std::set<std::string> &extensions);
+    static void getSupportedExtensions(std::set<QString> &extensions);
 
     virtual int getDecodeCompletion() const { return m_completion; }
 
@@ -52,8 +54,9 @@
     }
 
 protected:
-    std::string m_path;
-    std::string m_title;
+    QString m_path;
+    QString m_error;
+    QString m_title;
 
     OGGZ *m_oggz;
     FishSound *m_fishSound;
--- a/data/fileio/QuickTimeFileReader.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/QuickTimeFileReader.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -48,7 +48,7 @@
 };
 
 
-QuickTimeFileReader::QuickTimeFileReader(std::string path,
+QuickTimeFileReader::QuickTimeFileReader(QString path,
                                          DecodeMode decodeMode,
                                          CacheMode mode) :
     CodedAudioFileReader(mode),
@@ -74,7 +74,7 @@
 #else
     m_d->err = Gestalt(gestaltQuickTime,&QTversion);
     if ((m_d->err != noErr) || (QTversion < 0x07000000)) {
-        setError("Failed to find compatible version of QuickTime (version 7 or above required)");
+        m_error = QString("Failed to find compatible version of QuickTime (version 7 or above required)");
         return;
     }
 #endif 
@@ -100,7 +100,7 @@
         (url, 0, &dataRef, &dataRefType);
 
     if (m_d->err) { 
-        setError("Error creating data reference for QuickTime decoder", m_d->err);
+        m_error = QString("Error creating data reference for QuickTime decoder: code %1").arg(m_d->err);
         return;
     }
     
@@ -111,7 +111,7 @@
 
     DisposeHandle(dataRef);
     if (m_d->err) { 
-        setError("Error creating new movie for QuickTime decoder", m_d->err); 
+        m_error = QString("Error creating new movie for QuickTime decoder: code %1").arg(m_d->err); 
         return;
     }
 
@@ -140,10 +140,10 @@
     }
 	
     if (m_d->err && m_d->err != kQTPropertyNotSupportedErr) { 
-        setError("Error checking for DRM in QuickTime decoder", m_d->err);
+        m_error = QString("Error checking for DRM in QuickTime decoder: code %1").arg(m_d->err);
         return;
     } else if (!m_d->err && isProtected) { 
-        setError("File is protected with DRM");
+        m_error = QString("File is protected with DRM");
         return;
     } else if (m_d->err == kQTPropertyNotSupportedErr && !isProtected) {
         std::cerr << "QuickTime: File is not protected with DRM" << std::endl;
@@ -153,18 +153,18 @@
         SetMovieActive(m_d->movie, TRUE);
         m_d->err = GetMoviesError();
         if (m_d->err) {
-            setError("Error in QuickTime decoder activation", m_d->err);
+            m_error = QString("Error in QuickTime decoder activation: code %1").arg(m_d->err);
             return;
         }
     } else {
-	setError("Error in QuickTime decoder: Movie object not valid");
+	m_error = QString("Error in QuickTime decoder: Movie object not valid");
 	return;
     }
     
     m_d->err = MovieAudioExtractionBegin
         (m_d->movie, 0, &m_d->extractionSessionRef);
     if (m_d->err) {
-        setError("Error in QuickTime decoder extraction init", m_d->err);
+        m_error = QString("Error in QuickTime decoder extraction init: code %1").arg(m_d->err);
         return;
     }
 
@@ -176,7 +176,7 @@
          nil);
 
     if (m_d->err) {
-        setError("Error in QuickTime decoder property get", m_d->err);
+        m_error = QString("Error in QuickTime decoder property get: code %1").arg(m_d->err);
         return;
     }
 	
@@ -201,7 +201,7 @@
          &m_d->asbd);
 
     if (m_d->err) {
-        setError("Error in QuickTime decoder property set", m_d->err);
+        m_error = QString("Error in QuickTime decoder property set: code %1").arg(m_d->err);
         return;
     }
 
@@ -217,7 +217,7 @@
     if (decodeMode == DecodeAtOnce) {
 
 	m_progress = new QProgressDialog
-	    (QObject::tr("Decoding %1...").arg(QFileInfo(path.c_str()).fileName()),
+	    (QObject::tr("Decoding %1...").arg(QFileInfo(path).fileName()),
 	     QObject::tr("Stop"), 0, 100);
 	m_progress->hide();
 
@@ -229,7 +229,8 @@
                 (m_d->extractionSessionRef, &framesRead, &m_d->buffer,
                  &extractionFlags);
             if (m_d->err) {
-                setError("Error in QuickTime decoding", m_d->err);
+                m_error = QString("Error in QuickTime decoding: code %1")
+                    .arg(m_d->err);
                 break;
             }
 
@@ -249,7 +250,7 @@
 
         m_d->err = MovieAudioExtractionEnd(m_d->extractionSessionRef);
         if (m_d->err) {
-            setError("Error ending QuickTime extraction session", m_d->err);
+            m_error = QString("Error ending QuickTime extraction session: code %1").arg(m_d->err);
         }
 
         m_completion = 100;
@@ -264,7 +265,7 @@
         }
     }
 
-    std::cerr << "QuickTimeFileReader::QuickTimeFileReader: frame count is now " << getFrameCount() << ", error is \"\"" << m_error << "\"" << std::endl;
+    std::cerr << "QuickTimeFileReader::QuickTimeFileReader: frame count is now " << getFrameCount() << ", error is \"\"" << m_error.toStdString() << "\"" << std::endl;
 }
 
 QuickTimeFileReader::~QuickTimeFileReader()
@@ -295,8 +296,8 @@
             (m_reader->m_d->extractionSessionRef, &framesRead,
              &m_reader->m_d->buffer, &extractionFlags);
         if (m_reader->m_d->err) {
-            m_reader->setError("Error in QuickTime decoding",
-                               m_reader->m_d->err);
+            m_reader->m_error = QString("Error in QuickTime decoding: code %1")
+                .arg(m_reader->m_d->err);
             break;
         }
        
@@ -314,14 +315,14 @@
     
     m_reader->m_d->err = MovieAudioExtractionEnd(m_reader->m_d->extractionSessionRef);
     if (m_reader->m_d->err) {
-        m_reader->setError("Error ending QuickTime extraction session", m_reader->m_d->err);
+        m_reader->m_error = QString("Error ending QuickTime extraction session: code %1").arg(m_reader->m_d->err);
     }
     
     m_reader->m_completion = 100;
 } 
 
 void
-QuickTimeFileReader::getSupportedExtensions(std::set<std::string> &extensions)
+QuickTimeFileReader::getSupportedExtensions(std::set<QString> &extensions)
 {
     extensions.insert("aiff");
     extensions.insert("au");
--- a/data/fileio/QuickTimeFileReader.h	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/QuickTimeFileReader.h	Fri Aug 24 11:41:48 2007 +0000
@@ -37,14 +37,14 @@
         DecodeThreaded // decode in a background thread after construction
     };
 
-    QuickTimeFileReader(std::string path,
-                        DecodeMode decodeMode,
+    QuickTimeFileReader(QString path, DecodeMode decodeMode,
                         CacheMode cacheMode);
     virtual ~QuickTimeFileReader();
 
-    virtual std::string getTitle() const { return m_title; }
+    virtual QString getError() const { return m_error; }
+    virtual QString getTitle() const { return m_title; }
     
-    static void getSupportedExtensions(std::set<std::string> &extensions);
+    static void getSupportedExtensions(std::set<QString> &extensions);
 
     virtual int getDecodeCompletion() const { return m_completion; }
 
@@ -53,8 +53,9 @@
     }
 
 protected:
-    std::string m_path;
-    std::string m_title;
+    QString m_path;
+    QString m_error;
+    QString m_title;
 
     class D;
     D *m_d;
--- a/data/fileio/WavFileReader.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/WavFileReader.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -19,7 +19,7 @@
 
 #include <QMutexLocker>
 
-WavFileReader::WavFileReader(std::string path, bool fileUpdating) :
+WavFileReader::WavFileReader(QString path, bool fileUpdating) :
     m_file(0),
     m_path(path),
     m_buffer(0),
@@ -34,16 +34,18 @@
 
     m_fileInfo.format = 0;
     m_fileInfo.frames = 0;
-    m_file = sf_open(m_path.c_str(), SFM_READ, &m_fileInfo);
+    m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
 
     if (!m_file || (!fileUpdating && m_fileInfo.channels <= 0)) {
 	std::cerr << "WavFileReader::initialize: Failed to open file ("
 		  << sf_strerror(m_file) << ")" << std::endl;
 
 	if (m_file) {
-	    setError("Couldn't load audio file", sf_strerror(m_file));
+	    m_error = QString("Couldn't load audio file '%1':\n%2")
+		.arg(m_path).arg(sf_strerror(m_file));
 	} else {
-	    setError("Failed to open audio file");
+	    m_error = QString("Failed to open audio file '%1'")
+		.arg(m_path);
 	}
 	return;
     }
@@ -72,7 +74,7 @@
 
     if (m_file) {
         sf_close(m_file);
-        m_file = sf_open(m_path.c_str(), SFM_READ, &m_fileInfo);
+        m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
         if (!m_file || m_fileInfo.channels <= 0) {
             std::cerr << "WavFileReader::updateFrameCount: Failed to open file ("
                       << sf_strerror(m_file) << ")" << std::endl;
@@ -162,7 +164,7 @@
 }
 
 void
-WavFileReader::getSupportedExtensions(std::set<std::string> &extensions)
+WavFileReader::getSupportedExtensions(std::set<QString> &extensions)
 {
     int count;
 
--- a/data/fileio/WavFileReader.h	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/fileio/WavFileReader.h	Fri Aug 24 11:41:48 2007 +0000
@@ -26,9 +26,11 @@
 class WavFileReader : public AudioFileReader
 {
 public:
-    WavFileReader(std::string path, bool fileUpdating = false);
+    WavFileReader(QString path, bool fileUpdating = false);
     virtual ~WavFileReader();
 
+    virtual QString getError() const { return m_error; }
+
     /** 
      * Must be safe to call from multiple threads with different
      * arguments on the same object at the same time.
@@ -36,7 +38,7 @@
     virtual void getInterleavedFrames(size_t start, size_t count,
 				      SampleBlock &frames) const;
     
-    static void getSupportedExtensions(std::set<std::string> &extensions);
+    static void getSupportedExtensions(std::set<QString> &extensions);
 
     virtual int getDecodeCompletion() const { return 100; }
 
@@ -49,7 +51,8 @@
     SF_INFO m_fileInfo;
     SNDFILE *m_file;
 
-    std::string m_path;
+    QString m_path;
+    QString m_error;
 
     mutable QMutex m_mutex;
     mutable float *m_buffer;
--- a/data/model/Model.h	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/model/Model.h	Fri Aug 24 11:41:48 2007 +0000
@@ -21,6 +21,8 @@
 
 #include "base/XmlExportable.h"
 
+typedef std::vector<float> SampleBlock;
+
 class ZoomConstraint;
 
 /** 
--- a/data/model/WaveFileModel.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/model/WaveFileModel.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -46,8 +46,8 @@
     m_lastFillExtent(0),
     m_exiting(false)
 {
-    m_reader = AudioFileReaderFactory::createReader(path.toStdString());
-    setObjectName(m_reader->getTitle().c_str());
+    m_reader = AudioFileReaderFactory::createReader(path);
+    setObjectName(m_reader->getTitle());
     if (objectName() == "") setObjectName(QFileInfo(path).fileName());
     if (isOK()) fillCache();
 }
@@ -60,8 +60,8 @@
     m_lastFillExtent(0),
     m_exiting(false)
 {
-    m_reader = AudioFileReaderFactory::createReader(path.toStdString());
-    setObjectName(m_reader->getTitle().c_str());
+    m_reader = AudioFileReaderFactory::createReader(path);
+    setObjectName(m_reader->getTitle());
     if (objectName() == "") setObjectName(QFileInfo(originalLocation).fileName());
     if (isOK()) fillCache();
 }
@@ -75,7 +75,7 @@
     m_exiting(false)
 {
     m_reader = reader;
-    setObjectName(m_reader->getTitle().c_str());
+    setObjectName(m_reader->getTitle());
     if (objectName() == "") setObjectName(QFileInfo(path).fileName());
     fillCache();
 }
@@ -171,7 +171,7 @@
 //              << start << ", " << end << "): calling reader" << std::endl;
 #endif
 
-    AudioFileReader::SampleBlock frames;
+    SampleBlock frames;
     m_reader->getInterleavedFrames(start, end - start, frames);
 
     size_t i = 0;
@@ -213,7 +213,7 @@
 
     if (!m_reader || !m_reader->isOK()) return 0;
 
-    AudioFileReader::SampleBlock frames;
+    SampleBlock frames;
     m_reader->getInterleavedFrames(start, end - start, frames);
 
     size_t i = 0;
@@ -272,7 +272,7 @@
 	// matter by putting a single cache in getInterleavedFrames
 	// for short queries.
 
-        AudioFileReader::SampleBlock frames;
+	SampleBlock frames;
 	m_reader->getInterleavedFrames(start, end - start, frames);
 	float max = 0.0, min = 0.0, total = 0.0;
 	size_t i = 0, count = 0;
@@ -478,7 +478,7 @@
     
     size_t frame = 0;
     size_t readBlockSize = 16384;
-    AudioFileReader::SampleBlock block;
+    SampleBlock block;
 
     if (!m_model.isOK()) return;
     
--- a/data/model/WritableWaveFileModel.cpp	Thu Aug 16 16:47:07 2007 +0000
+++ b/data/model/WritableWaveFileModel.cpp	Fri Aug 24 11:41:48 2007 +0000
@@ -58,8 +58,8 @@
         return;
     }
 
-    m_reader = new WavFileReader(m_writer->getPath().toStdString(), true);
-    if (m_reader->getError() != "") {
+    m_reader = new WavFileReader(m_writer->getPath(), true);
+    if (!m_reader->getError().isEmpty()) {
         std::cerr << "WritableWaveFileModel: Error in creating wave file reader" << std::endl;
         delete m_reader;
         m_reader = 0;