| 687 | } |
| 688 | |
| 689 | ExportResult PCMExportProcessor::Process(ExportProcessorDelegate& delegate) |
| 690 | { |
| 691 | delegate.SetStatusString(context.status); |
| 692 | |
| 693 | auto exportResult = ExportResult::Success; |
| 694 | |
| 695 | { |
| 696 | std::vector<char> dither; |
| 697 | if ((context.info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_24) { |
| 698 | dither.reserve(maxBlockLen * context.info.channels * SAMPLE_SIZE(int24Sample)); |
| 699 | } |
| 700 | |
| 701 | while (exportResult == ExportResult::Success) { |
| 702 | sf_count_t samplesWritten; |
| 703 | size_t numSamples = context.mixer->Process(); |
| 704 | if (numSamples == 0) |
| 705 | break; |
| 706 | |
| 707 | auto mixed = context.mixer->GetBuffer(); |
| 708 | |
| 709 | // Bug 1572: Not ideal, but it does add the desired dither |
| 710 | if ((context.info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_24) { |
| 711 | for (int c = 0; c < context.info.channels; ++c) { |
| 712 | CopySamples( |
| 713 | mixed + (c * SAMPLE_SIZE(context.format)), context.format, |
| 714 | dither.data() + (c * SAMPLE_SIZE(int24Sample)), int24Sample, |
| 715 | numSamples, gHighQualityDither, context.info.channels, context.info.channels |
| 716 | ); |
| 717 | // Copy back without dither |
| 718 | CopySamples( |
| 719 | dither.data() + (c * SAMPLE_SIZE(int24Sample)), int24Sample, |
| 720 | const_cast<samplePtr>(mixed) // PRL fix this! |
| 721 | + (c * SAMPLE_SIZE(context.format)), context.format, |
| 722 | numSamples, DitherType::none, context.info.channels, context.info.channels); |
| 723 | } |
| 724 | } |
| 725 | |
| 726 | if (context.format == int16Sample) |
| 727 | samplesWritten = SFCall<sf_count_t>(sf_writef_short, context.sf, (const short *)mixed, numSamples); |
| 728 | else |
| 729 | samplesWritten = SFCall<sf_count_t>(sf_writef_float, context.sf, (const float *)mixed, numSamples); |
| 730 | |
| 731 | if (static_cast<size_t>(samplesWritten) != numSamples) { |
| 732 | char buffer2[1000]; |
| 733 | sf_error_str(context.sf, buffer2, 1000); |
| 734 | //Used to give this error message |
| 735 | #if 0 |
| 736 | AudacityMessageBox( |
| 737 | XO( |
| 738 | /* i18n-hint: %s will be the error message from libsndfile, which |
| 739 | * is usually something unhelpful (and untranslated) like "system |
| 740 | * error" */ |
| 741 | "Error while writing %s file (disk full?).\nLibsndfile says \"%s\"") |
| 742 | .Format( formatStr, wxString::FromAscii(buffer2) )); |
| 743 | #else |
| 744 | // But better to give the same error message as for |
| 745 | // other cases of disk exhaustion. |
| 746 | // The thrown exception doesn't escape but GuardedCall |
nothing calls this directly
no test coverage detected