30 |
#include <gtkmm/messagedialog.h> |
#include <gtkmm/messagedialog.h> |
31 |
#endif |
#endif |
32 |
|
|
33 |
|
#include <stdio.h> |
34 |
|
#include <sndfile.h> |
35 |
|
|
36 |
#define _(String) gettext(String) |
#define _(String) gettext(String) |
37 |
|
|
38 |
template<class T> inline std::string ToString(T o) { |
template<class T> inline std::string ToString(T o) { |
855 |
sigc::mem_fun(*this, &MainWindow::on_action_add_group) |
sigc::mem_fun(*this, &MainWindow::on_action_add_group) |
856 |
); |
); |
857 |
actionGroup->add( |
actionGroup->add( |
858 |
Gtk::Action::create("AddSample", _("Add _Sample")), |
Gtk::Action::create("AddSample", _("Add _Sample(s)")), |
859 |
sigc::mem_fun(*this, &MainWindow::on_action_add_sample) |
sigc::mem_fun(*this, &MainWindow::on_action_add_sample) |
860 |
); |
); |
861 |
actionGroup->add( |
actionGroup->add( |
1643 |
} |
} |
1644 |
|
|
1645 |
void MainWindow::on_action_add_sample() { |
void MainWindow::on_action_add_sample() { |
1646 |
//TODO: open browse for file dialog for adding new samples |
if (!file) return; |
1647 |
|
// get selected group |
1648 |
|
Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection(); |
1649 |
|
Gtk::TreeModel::iterator it = sel->get_selected(); |
1650 |
|
if (!it) return; |
1651 |
|
Gtk::TreeModel::Row row = *it; |
1652 |
|
gig::Group* group = row[m_SamplesModel.m_col_group]; |
1653 |
|
if (!group) { // not a group, but a sample is selected (probably) |
1654 |
|
gig::Sample* sample = row[m_SamplesModel.m_col_sample]; |
1655 |
|
if (!sample) return; |
1656 |
|
it = row.parent(); // resolve parent (that is the sample's group) |
1657 |
|
if (!it) return; |
1658 |
|
row = *it; |
1659 |
|
group = row[m_SamplesModel.m_col_group]; |
1660 |
|
if (!group) return; |
1661 |
|
} |
1662 |
|
// show 'browse for file' dialog |
1663 |
|
Gtk::FileChooserDialog dialog(*this, _("Add Sample(s)")); |
1664 |
|
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); |
1665 |
|
dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); |
1666 |
|
dialog.set_select_multiple(true); |
1667 |
|
Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile (yet to do ;-) |
1668 |
|
soundfilter.add_pattern("*.wav"); |
1669 |
|
soundfilter.set_name("Sound Files"); |
1670 |
|
Gtk::FileFilter allpassfilter; // matches every file |
1671 |
|
allpassfilter.add_pattern("*.*"); |
1672 |
|
allpassfilter.set_name("All Files"); |
1673 |
|
dialog.add_filter(soundfilter); |
1674 |
|
dialog.add_filter(allpassfilter); |
1675 |
|
if (dialog.run() == Gtk::RESPONSE_OK) { |
1676 |
|
Glib::ustring error_files; |
1677 |
|
Glib::SListHandle<Glib::ustring> filenames = dialog.get_filenames(); |
1678 |
|
for (Glib::SListHandle<Glib::ustring>::iterator iter = filenames.begin(); iter != filenames.end(); ++iter) { |
1679 |
|
printf("Adding sample %s\n",(*iter).c_str()); |
1680 |
|
// use libsndfile to retrieve file informations |
1681 |
|
SF_INFO info; |
1682 |
|
info.format = 0; |
1683 |
|
SNDFILE* hFile = sf_open((*iter).c_str(), SFM_READ, &info); |
1684 |
|
try { |
1685 |
|
if (!hFile) throw std::string("could not open file"); |
1686 |
|
int bitdepth; |
1687 |
|
switch (info.format & 0xff) { |
1688 |
|
case SF_FORMAT_PCM_S8: |
1689 |
|
bitdepth = 8; |
1690 |
|
break; |
1691 |
|
case SF_FORMAT_PCM_16: |
1692 |
|
bitdepth = 16; |
1693 |
|
break; |
1694 |
|
case SF_FORMAT_PCM_24: |
1695 |
|
bitdepth = 24; |
1696 |
|
break; |
1697 |
|
case SF_FORMAT_PCM_32: |
1698 |
|
bitdepth = 32; |
1699 |
|
break; |
1700 |
|
default: |
1701 |
|
sf_close(hFile); // close sound file |
1702 |
|
throw std::string("format not supported"); // unsupported subformat (yet?) |
1703 |
|
} |
1704 |
|
// add a new sample to the .gig file |
1705 |
|
gig::Sample* sample = file->AddSample(); |
1706 |
|
sample->pInfo->Name = (*iter).raw(); |
1707 |
|
sample->Channels = info.channels; |
1708 |
|
sample->BitDepth = bitdepth; |
1709 |
|
sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels; |
1710 |
|
sample->SamplesPerSecond = info.samplerate; |
1711 |
|
// schedule resizing the sample (which will be done physically when File::Save() is called) |
1712 |
|
sample->Resize(info.frames); |
1713 |
|
// add sample to the tree view |
1714 |
|
Gtk::TreeModel::iterator iterSample = m_refSamplesTreeModel->append(row.children()); |
1715 |
|
Gtk::TreeModel::Row rowSample = *iterSample; |
1716 |
|
rowSample[m_SamplesModel.m_col_name] = sample->pInfo->Name.c_str(); |
1717 |
|
rowSample[m_SamplesModel.m_col_sample] = sample; |
1718 |
|
rowSample[m_SamplesModel.m_col_group] = NULL; |
1719 |
|
// close sound file |
1720 |
|
sf_close(hFile); |
1721 |
|
} catch (std::string what) { // remember the files that made trouble (and their cause) |
1722 |
|
if (error_files.size()) error_files += "\n"; |
1723 |
|
error_files += *iter += " (" + what + ")"; |
1724 |
|
} |
1725 |
|
} |
1726 |
|
// show error message box when some file(s) could not be opened / added |
1727 |
|
if (error_files.size()) { |
1728 |
|
Glib::ustring txt = "Could not add the following sample(s):\n" + error_files; |
1729 |
|
Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR); |
1730 |
|
msg.run(); |
1731 |
|
} |
1732 |
|
} |
1733 |
} |
} |
1734 |
|
|
1735 |
void MainWindow::on_action_remove_sample() { |
void MainWindow::on_action_remove_sample() { |