107{
108 outTracks.clear();
109
112
113 {
114
117
119 dlog.ShowModal();
120 if (!dlog.GetReturnCode())
121 return;
122
123 const int encoding = dlog.mEncoding;
124 unsigned numChannels = dlog.mChannels;
125 double rate = dlog.mRate;
126 sf_count_t offset = (sf_count_t)dlog.mOffset;
127 double percent = dlog.mPercent;
128
129 SF_INFO sndInfo = { 0 };
130 sndInfo.samplerate = (int)rate;
131 sndInfo.channels = (int)numChannels;
132 sndInfo.format = encoding | SF_FORMAT_RAW;
133
134 wxFile f;
136
137 if (f.Open(fileName)) {
138
139
140
141 sndFile.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &sndInfo, FALSE));
142 }
143
144 if (!sndFile){
146 sf_error_str((SNDFILE *)NULL,
str, 1000);
147 wxPrintf(
"%s\n",
str);
148
150 }
151
152
153 {
154 int result = sf_command(sndFile.get(), SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset));
155 if (result != 0) {
157 sf_error_str(sndFile.get(),
str, 1000);
158 wxPrintf(
"%s\n",
str);
159
161 }
162 }
163 SFCall<sf_count_t>(sf_seek, sndFile.get(), 0, SEEK_SET);
164
165 auto totalFrames =
166
168
169
170
171
172
173
174
175
176
179
180 results.resize(1);
181 auto &channels = results[0];
182 channels.resize(numChannels);
183
184 {
185
186 auto iter = channels.begin();
187 for (decltype(numChannels) c = 0; c < numChannels; ++iter, ++c)
189 }
190 const auto firstChannel = channels.begin()->get();
192
195
196 decltype(totalFrames) framescompleted = 0;
197 if (totalFrames < 0) {
198 wxASSERT(false);
199 totalFrames = 0;
200 }
201
202 auto msg =
XO(
"Importing %s").Format( wxFileName::FileName(fileName).GetFullName() );
203
204
206
207 size_t block;
208 do {
209 block =
211
212 sf_count_t sf_result;
214 sf_result = SFCall<sf_count_t>(sf_readf_short, sndFile.get(), (short *)srcbuffer.ptr(), block);
215 else
216 sf_result = SFCall<sf_count_t>(sf_readf_float, sndFile.get(), (float *)srcbuffer.ptr(), block);
217
218 if (sf_result >= 0) {
219 block = sf_result;
220 }
221 else {
222
223
225 }
226
227 if (block) {
228 auto iter = channels.begin();
229 for(decltype(numChannels) c = 0; c < numChannels; ++iter, ++c) {
231 for(decltype(block) j=0; j<block; j++)
232 ((short *)buffer.ptr())[j] =
233 ((short *)srcbuffer.ptr())[numChannels*j+c];
234 }
235 else {
236 for(decltype(block) j=0; j<block; j++)
237 ((float *)buffer.ptr())[j] =
238 ((float *)srcbuffer.ptr())[numChannels*j+c];
239 }
240
243 }
244 framescompleted += block;
245 }
246
247 updateResult = progress.Update(
248 framescompleted.as_long_long(),
249 totalFrames.as_long_long()
250 );
252 break;
253
254 } while (block > 0 && framescompleted < totalFrames);
255 }
256
259
260 if (!results.empty() && !results[0].empty()) {
261 for (const auto &channel : results[0])
262 channel->Flush();
263 outTracks.swap(results);
264 }
265}
std::vector< std::vector< std::shared_ptr< WaveTrack > > > TrackHolders
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Thrown for failure of file or database operations in deeply nested places.
static sampleFormat ChooseFormat(sampleFormat effectiveFormat)
Choose appropriate format, which will not be narrower than the specified one.
ImportRawDialog prompts you with options such as endianness and sample size to help you importing dat...
static ProjectRate & Get(AudacityProject &project)
Can be thrown when user cancels operations, as with a progress dialog. Delayed handler does nothing.
std::shared_ptr< WaveTrack > Create()
Creates an unnamed empty WaveTrack with default sample format and default rate.
Positions or offsets within audio files need a wide type.
constexpr auto maxBlockSize