Audacity 3.2.0
Classes | Enumerations | Functions
ImportRaw.cpp File Reference

Functions for guessing audio type and attempting to read from unknown sample audio data. Implements ImportRawDialog. More...

#include "ImportRaw.h"
#include "ImportPlugin.h"
#include "ImportUtils.h"
#include "AudioIOBase.h"
#include "FileFormats.h"
#include "Prefs.h"
#include "ProjectRate.h"
#include "SelectFile.h"
#include "ShuttleGui.h"
#include "UserException.h"
#include "WaveTrack.h"
#include "ProgressDialog.h"
#include <cmath>
#include <stdint.h>
#include <vector>
#include <wx/crt.h>
#include <wx/defs.h>
#include <wx/button.h>
#include <wx/choice.h>
#include <wx/combobox.h>
#include <wx/panel.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include "FormatClassifier.h"
#include "sndfile.h"
Include dependency graph for ImportRaw.cpp:

Go to the source code of this file.

Classes

class  ImportRawDialog
 ImportRawDialog prompts you with options such as endianness and sample size to help you importing data of an unknown format. More...
 

Enumerations

enum  { ChoiceID = 9000 , PlayID , DetectID }
 

Functions

void ImportRaw (const AudacityProject &project, wxWindow *parent, const wxString &fileName, WaveTrackFactory *trackFactory, TrackHolders &outTracks)
 
static int getEndianChoice (int sfFormat)
 

Detailed Description

Functions for guessing audio type and attempting to read from unknown sample audio data. Implements ImportRawDialog.

Definition in file ImportRaw.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
ChoiceID 
PlayID 
DetectID 

Definition at line 282 of file ImportRaw.cpp.

282 {
283 ChoiceID = 9000,
284 PlayID,
285 DetectID,
286};
@ PlayID
Definition: ImportRaw.cpp:284
@ DetectID
Definition: ImportRaw.cpp:285
@ ChoiceID
Definition: ImportRaw.cpp:283

Function Documentation

◆ getEndianChoice()

static int getEndianChoice ( int  sfFormat)
static

Definition at line 262 of file ImportRaw.cpp.

262 {
263 switch (sfFormat & SF_FORMAT_ENDMASK)
264 {
265 default:
266 case SF_ENDIAN_FILE:
267 return 0;
268 case SF_ENDIAN_LITTLE:
269 return 1;
270 case SF_ENDIAN_BIG:
271 return 2;
272 case SF_ENDIAN_CPU:
273 return 3;
274 }
275}

Referenced by ImportRawDialog::ImportRawDialog(), and ImportRawDialog::OnDetect().

Here is the caller graph for this function:

◆ ImportRaw()

void ImportRaw ( const AudacityProject project,
wxWindow *  parent,
const wxString &  fileName,
WaveTrackFactory trackFactory,
TrackHolders outTracks 
)

Definition at line 106 of file ImportRaw.cpp.

108{
109 outTracks.clear();
110
112 auto updateResult = ProgressResult::Success;
113
114 {
115 // On first run, set default sample rate from project rate
116 if (ImportRawDialog::mRate < 100.)
118
119 ImportRawDialog dlog(parent, fileName);
120 dlog.ShowModal();
121 if (!dlog.GetReturnCode())
122 return;
123
124 const int encoding = dlog.mEncoding;
125 unsigned numChannels = dlog.mChannels;
126 double rate = dlog.mRate;
127 sf_count_t offset = (sf_count_t)dlog.mOffset;
128 double percent = dlog.mPercent;
129
130 SF_INFO sndInfo = { 0 };
131 sndInfo.samplerate = (int)rate;
132 sndInfo.channels = (int)numChannels;
133 sndInfo.format = encoding | SF_FORMAT_RAW;
134
135 wxFile f; // will be closed when it goes out of scope
136 SFFile sndFile;
137
138 if (f.Open(fileName)) {
139 // Even though there is an sf_open() that takes a filename, use the one that
140 // takes a file descriptor since wxWidgets can open a file with a Unicode name and
141 // libsndfile can't (under Windows).
142 sndFile.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &sndInfo, FALSE));
143 }
144
145 if (!sndFile){
146 char str[1000];
147 sf_error_str((SNDFILE *)NULL, str, 1000);
148 wxPrintf("%s\n", str);
149
150 throw FileException{ FileException::Cause::Open, fileName };
151 }
152
153
154 {
155 int result = sf_command(sndFile.get(), SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset));
156 if (result != 0) {
157 char str[1000];
158 sf_error_str(sndFile.get(), str, 1000);
159 wxPrintf("%s\n", str);
160
161 throw FileException{ FileException::Cause::Read, fileName };
162 }
163 }
164 SFCall<sf_count_t>(sf_seek, sndFile.get(), 0, SEEK_SET);
165
166 auto totalFrames =
167 // fraction of a sf_count_t value
168 (sampleCount)(sndInfo.frames * percent / 100.0);
169
170 //
171 // Sample format:
172 //
173 // In general, go with the user's preferences. However, if
174 // the file is higher-quality, go with a format which preserves
175 // the quality of the original file.
176 //
177
180
181 results.resize(numChannels);
182 for (size_t c = 0; c < numChannels; ++c)
183 results[c] = trackFactory->Create(format, rate);
184
185 const auto maxBlockSize = results[0]->GetMaxBlockSize();
186
187 SampleBuffer srcbuffer(maxBlockSize * numChannels, format);
189
190 decltype(totalFrames) framescompleted = 0;
191 if (totalFrames < 0) {
192 wxASSERT(false);
193 totalFrames = 0;
194 }
195
196 auto msg = XO("Importing %s").Format( wxFileName::FileName(fileName).GetFullName() );
197
198 /* i18n-hint: 'Raw' means 'unprocessed' here and should usually be translated.*/
199 ProgressDialog progress(XO("Import Raw"), msg);
200
201 size_t block;
202 do {
203 block =
204 limitSampleBufferSize( maxBlockSize, totalFrames - framescompleted );
205
206 sf_count_t sf_result;
207 if (format == int16Sample)
208 sf_result = SFCall<sf_count_t>(sf_readf_short, sndFile.get(), (short *)srcbuffer.ptr(), block);
209 else
210 sf_result = SFCall<sf_count_t>(sf_readf_float, sndFile.get(), (float *)srcbuffer.ptr(), block);
211
212 if (sf_result >= 0) {
213 block = sf_result;
214 }
215 else {
216 // This is not supposed to happen, sndfile.h says result is always
217 // a count, not an invalid value for error
218 throw FileException{ FileException::Cause::Read, fileName };
219 }
220
221 if (block) {
222 size_t c = 0;
223 for (const auto &pChannel : results) {
224 if (format == int16Sample) {
225 for (decltype(block) j = 0; j < block; ++j)
226 ((short *)buffer.ptr())[j] =
227 ((short *)srcbuffer.ptr())[numChannels * j + c];
228 }
229 else {
230 for (decltype(block) j = 0; j < block; ++j)
231 ((float *)buffer.ptr())[j] =
232 ((float *)srcbuffer.ptr())[numChannels * j + c];
233 }
234
235 pChannel->Append(buffer.ptr(),
236 ((format == int16Sample) ? int16Sample : floatSample), block,
237 1, sf_subtype_to_effective_format(encoding));
238 ++c;
239 }
240 framescompleted += block;
241 }
242
243 updateResult = progress.Update(
244 framescompleted.as_long_long(),
245 totalFrames.as_long_long()
246 );
247 if (updateResult != ProgressResult::Success)
248 break;
249
250 } while (block > 0 && framescompleted < totalFrames);
251 }
252
253 if (updateResult == ProgressResult::Failed || updateResult == ProgressResult::Cancelled)
254 throw UserException{};
255
256 if (!results.empty())
257 outTracks.push_back(ImportUtils::MakeTracks(results));
258}
#define str(a)
sampleFormat sf_subtype_to_effective_format(unsigned int format)
Choose the narrowest value in the sampleFormat enumeration for a given libsndfile format.
XO("Cut/Copy/Paste")
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
constexpr sampleFormat int16Sample
Definition: SampleFormat.h:41
constexpr sampleFormat floatSample
Definition: SampleFormat.h:43
const auto project
Thrown for failure of file or database operations in deeply nested places.
Definition: FileException.h:19
ImportRawDialog prompts you with options such as endianness and sample size to help you importing dat...
Definition: ImportRaw.cpp:58
static double mRate
Definition: ImportRaw.cpp:75
std::vector< std::shared_ptr< WaveTrack > > NewChannelGroup
Definition: ImportUtils.h:39
static std::shared_ptr< TrackList > MakeTracks(const NewChannelGroup &channels)
Flush the given channels and group them into tracks.
Definition: ImportUtils.cpp:49
static sampleFormat ChooseFormat(sampleFormat effectiveFormat)
Choose appropriate format, which will not be narrower than the specified one.
Definition: ImportUtils.cpp:21
ProgressDialog Class.
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
double GetRate() const
Definition: ProjectRate.cpp:53
Can be thrown when user cancels operations, as with a progress dialog. Delayed handler does nothing.
Definition: UserException.h:17
std::shared_ptr< WaveTrack > Create()
Creates an unnamed empty WaveTrack with default sample format and default rate.
Definition: WaveTrack.cpp:499
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19

References ImportUtils::ChooseFormat(), WaveTrackFactory::Create(), floatSample, anonymous_namespace{ExportPCM.cpp}::format, ProjectRate::Get(), ProjectRate::GetRate(), int16Sample, limitSampleBufferSize(), anonymous_namespace{StaffPadTimeAndPitch.cpp}::maxBlockSize, ImportRawDialog::mChannels, ImportRawDialog::mEncoding, ImportRawDialog::mOffset, ImportRawDialog::mPercent, ImportRawDialog::mRate, FileException::Open, project, SampleBuffer::ptr(), FileException::Read, sf_subtype_to_effective_format(), str, BasicUI::Success, ProgressDialog::Update(), and XO().

Referenced by anonymous_namespace{FileMenus.cpp}::DoImport().

Here is the call graph for this function:
Here is the caller graph for this function: