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
181 results.resize(numChannels);
182 for (size_t c = 0; c < numChannels; ++c)
184
185 const auto maxBlockSize = results[0]->GetMaxBlockSize();
186
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
200
201 size_t block;
202 do {
203 block =
205
206 sf_count_t sf_result;
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
217
219 }
220
221 if (block) {
222 size_t c = 0;
223 for (const auto &pChannel : results) {
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(),
238 ++c;
239 }
240 framescompleted += block;
241 }
242
243 updateResult = progress.Update(
244 framescompleted.as_long_long(),
245 totalFrames.as_long_long()
246 );
248 break;
249
250 } while (block > 0 && framescompleted < totalFrames);
251 }
252
255
256 if (!results.empty())
258}
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
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...
std::vector< std::shared_ptr< WaveTrack > > NewChannelGroup
static std::shared_ptr< TrackList > MakeTracks(const NewChannelGroup &channels)
Flush the given channels and group them into tracks.
static sampleFormat ChooseFormat(sampleFormat effectiveFormat)
Choose appropriate format, which will not be narrower than the specified one.
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