Mercurial > hg > svcore
diff data/model/WritableWaveFileModel.h @ 1527:710e6250a401 zoom
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 17 Sep 2018 13:51:14 +0100 |
parents | 954d0cf29ca7 |
children | c01cbe41aeb5 |
line wrap: on
line diff
--- a/data/model/WritableWaveFileModel.h Mon Dec 12 15:18:52 2016 +0000 +++ b/data/model/WritableWaveFileModel.h Mon Sep 17 13:51:14 2018 +0100 @@ -28,18 +28,88 @@ Q_OBJECT public: - WritableWaveFileModel(sv_samplerate_t sampleRate, int channels, QString path = ""); + enum class Normalisation { None, Peak }; + + /** + * Create a WritableWaveFileModel of the given sample rate and + * channel count, storing data in a new float-type extended WAV + * file with the given path. If path is the empty string, the data + * will be stored in a newly-created temporary file. + * + * If normalisation == None, sample values will be written + * verbatim, and will be ready to read as soon as they have been + * written. Otherwise samples will be normalised on writing; this + * will require an additional pass and temporary file, and no + * samples will be available to read until after writeComplete() + * has returned. + */ + WritableWaveFileModel(QString path, + sv_samplerate_t sampleRate, + int channels, + Normalisation normalisation); + + /** + * Create a WritableWaveFileModel of the given sample rate and + * channel count, storing data in a new float-type extended WAV + * file in a temporary location. This is equivalent to passing an + * empty path to the constructor above. + * + * If normalisation == None, sample values will be written + * verbatim, and will be ready to read as soon as they have been + * written. Otherwise samples will be normalised on writing; this + * will require an additional pass and temporary file, and no + * samples will be available to read until after writeComplete() + * has returned. + */ + WritableWaveFileModel(sv_samplerate_t sampleRate, + int channels, + Normalisation normalisation); + + /** + * Create a WritableWaveFileModel of the given sample rate and + * channel count, storing data in a new float-type extended WAV + * file in a temporary location, and applying no normalisation. + * + * This is equivalent to passing an empty path and + * Normalisation::None to the first constructor above. + */ + WritableWaveFileModel(sv_samplerate_t sampleRate, + int channels); + ~WritableWaveFileModel(); /** * Call addSamples to append a block of samples to the end of the - * file. Caller should also call setWriteProportion() to update - * the progress of this file, if it has a known end point, and - * should call writeComplete() when the file has been written. + * file. + * + * This function only appends the samples to the file being + * written; it does not update the model's view of the samples in + * that file. That is, it updates the file on disc but the model + * itself does not change its content. This is because re-reading + * the file to update the model may be more expensive than adding + * the samples in the first place. If you are writing small + * numbers of samples repeatedly, you probably only want the model + * to update periodically rather than after every write. + * + * Call updateModel() periodically to tell the model to update its + * own view of the samples in the file being written. + * + * Call setWriteProportion() periodically if the file being + * written has known duration and you want the model to be able to + * report the write progress as a percentage. + * + * Call writeComplete() when the file has been completely written. */ - virtual bool addSamples(float **samples, sv_frame_t count); + virtual bool addSamples(const float *const *samples, sv_frame_t count); /** + * Tell the model to update its own (read) view of the (written) + * file. May cause modelChanged() and modelChangedWithin() to be + * emitted. See the comment to addSamples above for rationale. + */ + void updateModel(); + + /** * Set the proportion of the file which has been written so far, * as a percentage. This may be used to indicate progress. * @@ -56,7 +126,7 @@ /** * Indicate that writing is complete. You should call this even if - * you have never called setWriteProportion(). + * you have never called setWriteProportion() or updateModel(). */ void writeComplete(); @@ -110,9 +180,9 @@ void setStartFrame(sv_frame_t startFrame); - virtual std::vector<float> getData(int channel, sv_frame_t start, sv_frame_t count) const; + virtual floatvec_t getData(int channel, sv_frame_t start, sv_frame_t count) const; - virtual std::vector<std::vector<float>> getMultiChannelData(int fromchannel, int tochannel, sv_frame_t start, sv_frame_t count) const; + virtual std::vector<floatvec_t> getMultiChannelData(int fromchannel, int tochannel, sv_frame_t start, sv_frame_t count) const; virtual int getSummaryBlockSize(int desired) const; @@ -129,13 +199,35 @@ protected: ReadOnlyWaveFileModel *m_model; - WavFileWriter *m_writer; + + /** When normalising, this writer is used to write verbatim + * samples to the temporary file prior to + * normalisation. Otherwise it's null + */ + WavFileWriter *m_temporaryWriter; + QString m_temporaryPath; + + /** When not normalising, this writer is used to write verbatim + * samples direct to the target file. When normalising, it is + * used to write normalised samples to the target after the + * temporary file has been completed. But it is still created on + * initialisation, so that there is a file header ready for the + * reader to address. + */ + WavFileWriter *m_targetWriter; + QString m_targetPath; + WavFileReader *m_reader; + Normalisation m_normalisation; sv_samplerate_t m_sampleRate; int m_channels; sv_frame_t m_frameCount; sv_frame_t m_startFrame; int m_proportion; + +private: + void init(QString path = ""); + void normaliseToTarget(); }; #endif