108{
109 outTracks.clear();
110
113
114 {
115
118
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;
137
138 if (f.Open(fileName)) {
139
140
141
142 sndFile.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &sndInfo, FALSE));
143 }
144
145 if (!sndFile){
147 sf_error_str((SNDFILE *)NULL,
str, 1000);
148 wxPrintf(
"%s\n",
str);
149
151 }
152
153
154 {
155 int result = sf_command(sndFile.get(), SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset));
156 if (result != 0) {
158 sf_error_str(sndFile.get(),
str, 1000);
159 wxPrintf(
"%s\n",
str);
160
162 }
163 }
164 SFCall<sf_count_t>(sf_seek, sndFile.get(), 0, SEEK_SET);
165
166 auto totalFrames =
167
169
170
171
172
173
174
175
176
177
180
182
184
187
188 decltype(totalFrames) framescompleted = 0;
189 if (totalFrames < 0) {
190 wxASSERT(false);
191 totalFrames = 0;
192 }
193
194 auto msg =
XO(
"Importing %s").Format( wxFileName::FileName(fileName).GetFullName() );
195
196
198
199 size_t block;
200 do {
201 block =
203
204 sf_count_t sf_result;
206 sf_result = SFCall<sf_count_t>(sf_readf_short, sndFile.get(), (short *)srcbuffer.ptr(), block);
207 else
208 sf_result = SFCall<sf_count_t>(sf_readf_float, sndFile.get(), (float *)srcbuffer.ptr(), block);
209
210 if (sf_result >= 0) {
211 block = sf_result;
212 }
213 else {
214
215
217 }
218
219 if (block) {
220 size_t c = 0;
222 {
224 for (size_t j = 0; j < block; ++j)
225 ((short *)buffer.ptr())[j] =
226 ((short *)srcbuffer.ptr())[numChannels * j + c];
227 }
228 else {
229 for (size_t j = 0; j < block; ++j)
230 ((float *)buffer.ptr())[j] =
231 ((float *)srcbuffer.ptr())[numChannels * j + c];
232 }
233
234 channel.AppendBuffer(buffer.ptr(),
237 ++c;
238 });
239 framescompleted += block;
240 }
241
242 updateResult = progress.Update(
243 framescompleted.as_long_long(),
244 totalFrames.as_long_long()
245 );
247 break;
248
249 } while (block > 0 && framescompleted < totalFrames);
250 }
251
254
256}
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
std::shared_ptr< TrackList > TrackListHolder
Thrown for failure of file or database operations in deeply nested places.
ImportRawDialog prompts you with options such as endianness and sample size to help you importing dat...
static sampleFormat ChooseFormat(sampleFormat effectiveFormat)
Choose appropriate format, which will not be narrower than the specified one.
static void ForEachChannel(TrackList &trackList, const std::function< void(WaveChannel &)> &op)
Iterates over channels in each wave track from the list.
static void FinalizeImport(TrackHolders &outTracks, const std::vector< std::shared_ptr< WaveTrack > > &importedStreams)
Flushes the given channels and moves them to outTracks.
static ProjectRate & Get(AudacityProject &project)
Can be thrown when user cancels operations, as with a progress dialog. Delayed handler does nothing.
TrackListHolder CreateMany(size_t nChannels)
Creates tracks with project's default rate and format and the given number of channels.
A Track that contains audio waveform data.
Positions or offsets within audio files need a wide type.
constexpr auto maxBlockSize
const char * begin(const char *str) noexcept