Using QByteArray and QFile instead of FILE and int16_t, adapting to code style corrections?
This commit is contained in:
parent
d2881aad4b
commit
457d240854
148
src/ui/ripcd.cpp
148
src/ui/ripcd.cpp
@ -29,11 +29,7 @@
|
|||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include <QtConcurrentRun>
|
#include <QtConcurrentRun>
|
||||||
#include <cdio/cdda.h>
|
|
||||||
#include <cdio/cdio.h>
|
#include <cdio/cdio.h>
|
||||||
//#include <cdio/paranoia.h>
|
|
||||||
#include <cdio/cdtext.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <tag.h>
|
#include <tag.h>
|
||||||
#include <taglib.h>
|
#include <taglib.h>
|
||||||
#include <tfile.h>
|
#include <tfile.h>
|
||||||
@ -48,20 +44,37 @@
|
|||||||
# undef AddJob
|
# undef AddJob
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool ComparePresetsByName(const TranscoderPreset& left,
|
namespace {
|
||||||
|
bool ComparePresetsByName(const TranscoderPreset& left,
|
||||||
const TranscoderPreset& right) {
|
const TranscoderPreset& right) {
|
||||||
return left.name_ < right.name_;
|
return left.name_ < right.name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char kWavHeaderRiffMarker[] = "RIFF";
|
||||||
|
const char kWavFileTypeFormatChunk[] = "WAVEfmt ";
|
||||||
|
const char kWavDataString[] = "data";
|
||||||
|
|
||||||
|
const int kCheckboxColumn = 0;
|
||||||
|
const int kTrackNumberColumn = 1;
|
||||||
|
const int kTrackTitleColumn = 2;
|
||||||
|
|
||||||
|
}
|
||||||
const char* RipCD::kSettingsGroup = "Transcoder";
|
const char* RipCD::kSettingsGroup = "Transcoder";
|
||||||
const int RipCD::kProgressInterval = 500;
|
const int RipCD::kProgressInterval = 500;
|
||||||
const int RipCD::kMaxDestinationItems = 10;
|
const int RipCD::kMaxDestinationItems = 10;
|
||||||
|
|
||||||
RipCD::RipCD(QWidget* parent) :
|
RipCD::RipCD(QWidget* parent) :
|
||||||
QDialog(parent), transcoder_(new Transcoder(this)), queued_(0), finished_success_(
|
QDialog(parent),
|
||||||
0), finished_failed_(0), ui_(new Ui_RipCD()), checkboxes_(
|
transcoder_(new Transcoder(this)),
|
||||||
QList<QCheckBox*>()), generated_files_(QList<QString>()), tracks_to_rip_(
|
queued_(0),
|
||||||
QList<int>()), track_names_(QList<QLineEdit*>()) {
|
finished_success_(0),
|
||||||
|
finished_failed_(0),
|
||||||
|
ui_(new Ui_RipCD()),
|
||||||
|
checkboxes_(QList<QCheckBox*>()),
|
||||||
|
generated_files_(QList<QString>()),
|
||||||
|
tracks_to_rip_(QList<int>()),
|
||||||
|
track_names_(QList<QLineEdit*>())
|
||||||
|
{
|
||||||
// Init
|
// Init
|
||||||
ui_->setupUi(this);
|
ui_->setupUi(this);
|
||||||
cancel_button_ = ui_->button_box->button(QDialogButtonBox::Cancel);
|
cancel_button_ = ui_->button_box->button(QDialogButtonBox::Cancel);
|
||||||
@ -74,33 +87,32 @@ RipCD::RipCD(QWidget* parent) :
|
|||||||
connect(transcoder_, SIGNAL(JobOutputName(QString)),
|
connect(transcoder_, SIGNAL(JobOutputName(QString)),
|
||||||
SLOT(AppendOutput(QString)));
|
SLOT(AppendOutput(QString)));
|
||||||
connect(this, SIGNAL(RippingComplete()), SLOT(ThreadedTranscoding()));
|
connect(this, SIGNAL(RippingComplete()), SLOT(ThreadedTranscoding()));
|
||||||
connect(this, SIGNAL(signalUpdateProgress()), SLOT(UpdateProgress()));
|
connect(this, SIGNAL(SignalUpdateProgress()), SLOT(UpdateProgress()));
|
||||||
|
|
||||||
connect(ui_->options, SIGNAL(clicked()), SLOT(Options()));
|
connect(ui_->options, SIGNAL(clicked()), SLOT(Options()));
|
||||||
connect(ui_->select, SIGNAL(clicked()), SLOT(AddDestination()));
|
connect(ui_->select, SIGNAL(clicked()), SLOT(AddDestination()));
|
||||||
|
|
||||||
setWindowTitle(tr("Rip CD"));
|
setWindowTitle(tr("Rip CD"));
|
||||||
|
|
||||||
p_cdio_ = cdio_open(NULL, DRIVER_UNKNOWN);
|
cdio_ = cdio_open(NULL, DRIVER_UNKNOWN);
|
||||||
i_tracks = cdio_get_num_tracks(p_cdio_);
|
i_tracks = cdio_get_num_tracks(cdio_);
|
||||||
ui_->tableWidget->setRowCount(i_tracks);
|
ui_->tableWidget->setRowCount(i_tracks);
|
||||||
|
|
||||||
for (int i = 1; i <= i_tracks; i++) {
|
for (int i = 1; i <= i_tracks; i++) {
|
||||||
QCheckBox *_t = new QCheckBox(tr(""), ui_->tableWidget);
|
QCheckBox *checkbox_i = new QCheckBox(tr(""), ui_->tableWidget);
|
||||||
_t->click();
|
checkbox_i->click();
|
||||||
checkboxes_.append(_t);
|
checkboxes_.append(checkbox_i);
|
||||||
ui_->tableWidget->setCellWidget(i - 1, 0, _t);
|
ui_->tableWidget->setCellWidget(i - 1, kCheckboxColumn, checkbox_i);
|
||||||
ui_->tableWidget->setCellWidget(i - 1, 1, new QLabel(QString::number(i)));
|
ui_->tableWidget->setCellWidget(i - 1, kTrackNumberColumn, new QLabel(QString::number(i)));
|
||||||
QString _str_track;
|
QString track_title = QString("Track %1").arg(i);
|
||||||
_str_track = "Track %1";
|
QLineEdit *line_edit_track_title_i = new QLineEdit(track_title,ui_->tableWidget);
|
||||||
QLineEdit *_ql = new QLineEdit(_str_track.arg(QString::number(i)),
|
track_names_.append(line_edit_track_title_i);
|
||||||
ui_->tableWidget);
|
ui_->tableWidget->setCellWidget(i - 1, kTrackTitleColumn, line_edit_track_title_i);
|
||||||
track_names_.append(_ql);
|
|
||||||
ui_->tableWidget->setCellWidget(i - 1, 2, _ql);
|
|
||||||
}
|
}
|
||||||
// Get presets
|
// Get presets
|
||||||
QList < TranscoderPreset > presets = Transcoder::GetAllPresets();
|
QList <TranscoderPreset> presets = Transcoder::GetAllPresets();
|
||||||
qSort(presets.begin(), presets.end(), ComparePresetsByName);
|
qSort(presets.begin(), presets.end(), ComparePresetsByName);
|
||||||
foreach(const TranscoderPreset& preset, presets) {
|
for(const TranscoderPreset& preset : presets) {
|
||||||
ui_->format->addItem(
|
ui_->format->addItem(
|
||||||
QString("%1 (.%2)").arg(preset.name_, preset.extension_),
|
QString("%1 (.%2)").arg(preset.name_, preset.extension_),
|
||||||
QVariant::fromValue(preset));
|
QVariant::fromValue(preset));
|
||||||
@ -124,10 +136,35 @@ RipCD::RipCD(QWidget* parent) :
|
|||||||
ui_->progress_bar->setMaximum(100);
|
ui_->progress_bar->setMaximum(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RipCD::WriteWAVHeader(FILE *stream, int32_t i_bytecount) {
|
/*
|
||||||
fwrite("RIFF", sizeof(char), 4, stream);
|
* WAV Header documentation
|
||||||
|
* as taken from:
|
||||||
|
* http://www.topherlee.com/software/pcm-tut-wavformat.html
|
||||||
|
* Pos Value Description
|
||||||
|
* 0-3 | "RIFF" | Marks the file as a riff file.
|
||||||
|
* | Characters are each 1 byte long.
|
||||||
|
* 4-7 | File size (integer) | Size of the overall file - 8 bytes,
|
||||||
|
* | in bytes (32-bit integer).
|
||||||
|
* 8-11 | "WAVE" | File Type Header. For our purposes,
|
||||||
|
* | it always equals "WAVE".
|
||||||
|
* 13-16 | "fmt " | Format chunk marker. Includes trailing null.
|
||||||
|
* 17-20 | 16 | Length of format data as listed above
|
||||||
|
* 21-22 | 1 | Type of format (1 is PCM) - 2 byte integer
|
||||||
|
* 23-24 | 2 | Number of Channels - 2 byte integer
|
||||||
|
* 25-28 | 44100 | Sample Rate - 32 byte integer. Common values
|
||||||
|
* | are 44100 (CD), 48000 (DAT).
|
||||||
|
* | Sample Rate = Number of Samples per second, or Hertz.
|
||||||
|
* 29-32 | 176400 | (Sample Rate * BitsPerSample * Channels) / 8.
|
||||||
|
* 33-34 | 4 | (BitsPerSample * Channels) / 8.1 - 8 bit mono2 - 8 bit stereo/16 bit mono4 - 16 bit stereo
|
||||||
|
* 35-36 | 16 | Bits per sample
|
||||||
|
* 37-40 | "data" | "data" chunk header.
|
||||||
|
* | Marks the beginning of the data section.
|
||||||
|
* 41-44 | File size (data) | Size of the data section.
|
||||||
|
*/
|
||||||
|
void RipCD::WriteWAVHeader(QFile *stream, int32_t i_bytecount) {
|
||||||
|
stream->write(kWavHeaderRiffMarker); /* 0-3 */
|
||||||
PutNum(i_bytecount + 44 - 8, stream, 4); /* 4-7 */
|
PutNum(i_bytecount + 44 - 8, stream, 4); /* 4-7 */
|
||||||
fwrite("WAVEfmt ", sizeof(char), 8, stream); /* 8-15 */
|
stream->write(kWavFileTypeFormatChunk); /* 8-15 */
|
||||||
PutNum(16, stream, 4); /* 16-19 */
|
PutNum(16, stream, 4); /* 16-19 */
|
||||||
PutNum(1, stream, 2); /* 20-21 */
|
PutNum(1, stream, 2); /* 20-21 */
|
||||||
PutNum(2, stream, 2); /* 22-23 */
|
PutNum(2, stream, 2); /* 22-23 */
|
||||||
@ -135,17 +172,17 @@ void RipCD::WriteWAVHeader(FILE *stream, int32_t i_bytecount) {
|
|||||||
PutNum(44100 * 2 * 2, stream, 4); /* 28-31 */
|
PutNum(44100 * 2 * 2, stream, 4); /* 28-31 */
|
||||||
PutNum(4, stream, 2); /* 32-33 */
|
PutNum(4, stream, 2); /* 32-33 */
|
||||||
PutNum(16, stream, 2); /* 34-35 */
|
PutNum(16, stream, 2); /* 34-35 */
|
||||||
fwrite("data", sizeof(char), 4, stream); /* 36-39 */
|
stream->write(kWavDataString); /* 36-39 */
|
||||||
PutNum(i_bytecount, stream, 4); /* 40-43 */
|
PutNum(i_bytecount, stream, 4); /* 40-43 */
|
||||||
}
|
}
|
||||||
|
|
||||||
void RipCD::PutNum(int64_t num, FILE *stream, int bytes) {
|
void RipCD::PutNum(int64_t num, QFile *stream, int bytes) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
|
||||||
for (i = 0; bytes--; i++) {
|
for (i = 0; bytes--; i++) {
|
||||||
c = (num >> (i << 3)) & 0xff;
|
c = (num >> (i << 3)) & 0xff;
|
||||||
if (fwrite(&c, sizeof(char), 1, stream) == -1) {
|
if (stream->write(reinterpret_cast<char*>(&c), sizeof(c)) == -1) {
|
||||||
perror("Could not write to output.");
|
perror("Could not write to output.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -155,7 +192,7 @@ void RipCD::PutNum(int64_t num, FILE *stream, int bytes) {
|
|||||||
int RipCD::NumTracksToRip() {
|
int RipCD::NumTracksToRip() {
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for (int i = 0; i < checkboxes_.length(); i++) {
|
for (int i = 0; i < checkboxes_.length(); i++) {
|
||||||
if (checkboxes_.value(i)->isChecked() == true) {
|
if (checkboxes_.value(i)->isChecked()) {
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,43 +206,41 @@ void RipCD::ThreadClickedRipButton() {
|
|||||||
finished_failed_ = 0;
|
finished_failed_ = 0;
|
||||||
ui_->progress_bar->setMaximum(NumTracksToRip() * 2 * 100);
|
ui_->progress_bar->setMaximum(NumTracksToRip() * 2 * 100);
|
||||||
|
|
||||||
|
// Set up progress bar
|
||||||
emit(SignalUpdateProgress());
|
emit(SignalUpdateProgress());
|
||||||
|
|
||||||
// Set up the progressbar
|
|
||||||
|
|
||||||
for (int i = 1; i <= i_tracks; i++) {
|
for (int i = 1; i <= i_tracks; i++) {
|
||||||
if (checkboxes_.value(i - 1)->isChecked() == false) {
|
if (!checkboxes_.value(i - 1)->isChecked()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tracks_to_rip_.append(i);
|
tracks_to_rip_.append(i);
|
||||||
lsn_t i_first_lsn = cdio_get_track_lsn(p_cdio_, i);
|
|
||||||
lsn_t i_last_lsn = cdio_get_track_last_lsn(p_cdio_, i);
|
|
||||||
|
|
||||||
lsn_t i_cursor;
|
|
||||||
int16_t *p_readbuf = reinterpret_cast<int16_t *>
|
|
||||||
(calloc(CDIO_CD_FRAMESIZE_RAW, 1));
|
|
||||||
|
|
||||||
QString filename = source_directory
|
QString filename = source_directory
|
||||||
+ ParseFileFormatString(ui_->format_filename->text(), i) + ".wav";
|
+ ParseFileFormatString(ui_->format_filename->text(), i) + ".wav";
|
||||||
FILE *fp = fopen(filename.toUtf8().constData(), "w");
|
QFile* destination_file = new QFile(filename);
|
||||||
WriteWAVHeader(fp,
|
destination_file->open(QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
lsn_t i_first_lsn = cdio_get_track_lsn(cdio_, i);
|
||||||
|
lsn_t i_last_lsn = cdio_get_track_last_lsn(cdio_, i);
|
||||||
|
WriteWAVHeader(destination_file,
|
||||||
(i_last_lsn - i_first_lsn + 1) * CDIO_CD_FRAMESIZE_RAW);
|
(i_last_lsn - i_first_lsn + 1) * CDIO_CD_FRAMESIZE_RAW);
|
||||||
|
|
||||||
for (i_cursor = i_first_lsn; i_cursor <= i_last_lsn; i_cursor++) {
|
QByteArray *buffered_input_bytes = new QByteArray();
|
||||||
cdio_read_audio_sector(p_cdio_, p_readbuf, i_cursor);
|
buffered_input_bytes->resize(CDIO_CD_FRAMESIZE_RAW);
|
||||||
if (!p_readbuf) {
|
for (lsn_t i_cursor = i_first_lsn; i_cursor <= i_last_lsn; i_cursor++) {
|
||||||
|
cdio_read_audio_sector(cdio_, buffered_input_bytes->data(), i_cursor);
|
||||||
|
if (!buffered_input_bytes->data()) {
|
||||||
qDebug() << "Read error. Stopping.";
|
qDebug() << "Read error. Stopping.";
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
fwrite(p_readbuf, 1, CDIO_CD_FRAMESIZE_RAW, fp);
|
destination_file->write(buffered_input_bytes->data(), CDIO_CD_FRAMESIZE_RAW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finished_success_++;
|
finished_success_++;
|
||||||
emit(SignalUpdateProgress());
|
emit(SignalUpdateProgress());
|
||||||
fclose(fp);
|
destination_file->close();
|
||||||
free(p_readbuf);
|
delete buffered_input_bytes;
|
||||||
p_readbuf = NULL;
|
|
||||||
|
|
||||||
TranscoderPreset preset =
|
TranscoderPreset preset =
|
||||||
ui_->format->itemData(ui_->format->currentIndex())
|
ui_->format->itemData(ui_->format->currentIndex())
|
||||||
.value<TranscoderPreset>();
|
.value<TranscoderPreset>();
|
||||||
@ -236,15 +271,15 @@ QString RipCD::GetOutputFileName(const QString& input,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString RipCD::ParseFileFormatString(const QString& file_format,
|
QString RipCD::ParseFileFormatString(const QString& file_format,
|
||||||
int trackNo) const {
|
int track_no) const {
|
||||||
QString to_return = file_format;
|
QString to_return = file_format;
|
||||||
to_return.replace(QString("%artist%"), ui_->artistLineEdit->text());
|
to_return.replace(QString("%artist%"), ui_->artistLineEdit->text());
|
||||||
to_return.replace(QString("%album%"), ui_->albumLineEdit->text());
|
to_return.replace(QString("%album%"), ui_->albumLineEdit->text());
|
||||||
to_return.replace(QString("%genre%"), ui_->genreLineEdit->text());
|
to_return.replace(QString("%genre%"), ui_->genreLineEdit->text());
|
||||||
to_return.replace(QString("%year%"), ui_->yearLineEdit->text());
|
to_return.replace(QString("%year%"), ui_->yearLineEdit->text());
|
||||||
to_return.replace(QString("%tracknum%"), QString::number(trackNo));
|
to_return.replace(QString("%tracknum%"), QString::number(track_no));
|
||||||
to_return.replace(QString("%track%"),
|
to_return.replace(QString("%track%"),
|
||||||
track_names_.value(trackNo - 1)->text());
|
track_names_.value(track_no - 1)->text());
|
||||||
return to_return;
|
return to_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,8 +317,7 @@ void RipCD::AllJobsComplete() {
|
|||||||
// having a little trouble on wav files, works fine on ogg-vorbis
|
// having a little trouble on wav files, works fine on ogg-vorbis
|
||||||
qSort(generated_files_);
|
qSort(generated_files_);
|
||||||
|
|
||||||
int i;
|
for (int i = 0; i < generated_files_.length(); i++) {
|
||||||
for (i = 0; i < generated_files_.length(); i++) {
|
|
||||||
TagLib::FileRef f(generated_files_.value(i).toUtf8().constData());
|
TagLib::FileRef f(generated_files_.value(i).toUtf8().constData());
|
||||||
|
|
||||||
f.tag()->setTitle(
|
f.tag()->setTitle(
|
||||||
@ -303,7 +337,7 @@ void RipCD::AllJobsComplete() {
|
|||||||
tracks_to_rip_.clear();
|
tracks_to_rip_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RipCD::AppendOutput(const QString &filename) {
|
void RipCD::AppendOutput(const QString& filename) {
|
||||||
generated_files_.append(filename);
|
generated_files_.append(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,18 +35,18 @@ class RipCD: public QDialog {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RipCD(QWidget* parent = 0);
|
explicit RipCD(QWidget* parent = 0);
|
||||||
|
|
||||||
|
private:
|
||||||
static const char* kSettingsGroup;
|
static const char* kSettingsGroup;
|
||||||
static const int kProgressInterval;
|
static const int kProgressInterval;
|
||||||
static const int kMaxDestinationItems;
|
static const int kMaxDestinationItems;
|
||||||
|
|
||||||
private:
|
|
||||||
Transcoder* transcoder_;
|
Transcoder* transcoder_;
|
||||||
int queued_;
|
int queued_;
|
||||||
int finished_success_;
|
int finished_success_;
|
||||||
int finished_failed_;
|
int finished_failed_;
|
||||||
track_t i_tracks;
|
track_t i_tracks;
|
||||||
Ui_RipCD* ui_;
|
Ui_RipCD* ui_;
|
||||||
CdIo_t *p_cdio_;
|
CdIo_t *cdio_;
|
||||||
QList<QCheckBox*> checkboxes_;
|
QList<QCheckBox*> checkboxes_;
|
||||||
QList<QString> generated_files_;
|
QList<QString> generated_files_;
|
||||||
QList<int> tracks_to_rip_;
|
QList<int> tracks_to_rip_;
|
||||||
@ -54,14 +54,14 @@ class RipCD: public QDialog {
|
|||||||
QString last_add_dir_;
|
QString last_add_dir_;
|
||||||
QPushButton* cancel_button_;
|
QPushButton* cancel_button_;
|
||||||
|
|
||||||
void WriteWAVHeader(FILE *stream, int32_t i_bytecount);
|
void WriteWAVHeader(QFile* stream, int32_t i_bytecount);
|
||||||
void PutNum(int64_t num, FILE *stream, int bytes);
|
void PutNum(int64_t num, QFile* stream, int bytes);
|
||||||
int NumTracksToRip();
|
int NumTracksToRip();
|
||||||
void ThreadClickedRipButton();
|
void ThreadClickedRipButton();
|
||||||
QString TrimPath(const QString& path) const;
|
QString TrimPath(const QString& path) const;
|
||||||
QString GetOutputFileName(const QString& input,
|
QString GetOutputFileName(const QString& input,
|
||||||
const TranscoderPreset& preset) const;
|
const TranscoderPreset& preset) const;
|
||||||
QString ParseFileFormatString(const QString& file_format, int trackNo) const;
|
QString ParseFileFormatString(const QString& file_format, int track_no) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void RippingComplete();
|
void RippingComplete();
|
||||||
@ -72,7 +72,7 @@ class RipCD: public QDialog {
|
|||||||
void ClickedRipButton();
|
void ClickedRipButton();
|
||||||
void JobComplete(const QString& filename, bool success);
|
void JobComplete(const QString& filename, bool success);
|
||||||
void AllJobsComplete();
|
void AllJobsComplete();
|
||||||
void AppendOutput(const QString &filename);
|
void AppendOutput(const QString& filename);
|
||||||
void Options();
|
void Options();
|
||||||
void AddDestination();
|
void AddDestination();
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user