/[svn]/gigedit/trunk/src/gigedit/mainwindow.cpp
ViewVC logotype

Diff of /gigedit/trunk/src/gigedit/mainwindow.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1261 by persson, Thu Jul 5 17:12:20 2007 UTC revision 1328 by schoenebeck, Fri Sep 7 21:18:31 2007 UTC
# Line 31  Line 31 
31  #include <gtkmm/aboutdialog.h>  #include <gtkmm/aboutdialog.h>
32  #endif  #endif
33    
34    #if (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION < 6) || GLIBMM_MAJOR_VERSION < 2
35    namespace Glib {
36    Glib::ustring filename_display_basename(const std::string& filename)
37    {
38        gchar* gstr = g_path_get_basename(filename.c_str());
39        Glib::ustring str(gstr);
40        g_free(gstr);
41        return Glib::filename_to_utf8(str);
42    }
43    }
44    #endif
45    
46  #include <stdio.h>  #include <stdio.h>
47  #include <sndfile.h>  #include <sndfile.h>
48    
# Line 234  MainWindow::MainWindow() Line 246  MainWindow::MainWindow()
246      std::list<Gtk::TargetEntry> drag_target_gig_sample;      std::list<Gtk::TargetEntry> drag_target_gig_sample;
247      drag_target_gig_sample.push_back( Gtk::TargetEntry("gig::Sample") );      drag_target_gig_sample.push_back( Gtk::TargetEntry("gig::Sample") );
248      m_TreeViewSamples.drag_source_set(drag_target_gig_sample);      m_TreeViewSamples.drag_source_set(drag_target_gig_sample);
249        m_TreeViewSamples.signal_drag_begin().connect(
250            sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_begin)
251        );
252      m_TreeViewSamples.signal_drag_data_get().connect(      m_TreeViewSamples.signal_drag_data_get().connect(
253          sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_data_get)          sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_data_get)
254      );      );
# Line 242  MainWindow::MainWindow() Line 257  MainWindow::MainWindow()
257          sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)          sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)
258      );      );
259      dimreg_edit.signal_dimreg_changed().connect(      dimreg_edit.signal_dimreg_changed().connect(
260          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::hide(sigc::mem_fun(*this, &MainWindow::file_changed)));
261      m_RegionChooser.signal_instrument_changed().connect(      m_RegionChooser.signal_instrument_changed().connect(
262          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
263      m_DimRegionChooser.signal_region_changed().connect(      m_DimRegionChooser.signal_region_changed().connect(
264          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
265      instrumentProps.signal_instrument_changed().connect(      instrumentProps.signal_instrument_changed().connect(
266          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
267    
268        dimreg_edit.signal_dimreg_to_be_changed().connect(
269            dimreg_to_be_changed_signal.make_slot());
270        dimreg_edit.signal_dimreg_changed().connect(
271            dimreg_changed_signal.make_slot());
272        dimreg_edit.signal_sample_ref_changed().connect(
273            sample_ref_changed_signal.make_slot());
274    
275        m_RegionChooser.signal_instrument_struct_to_be_changed().connect(
276            sigc::hide(
277                sigc::bind(
278                    file_structure_to_be_changed_signal.make_slot(),
279                    sigc::ref(this->file)
280                )
281            )
282        );
283        m_RegionChooser.signal_instrument_struct_changed().connect(
284            sigc::hide(
285                sigc::bind(
286                    file_structure_changed_signal.make_slot(),
287                    sigc::ref(this->file)
288                )
289            )
290        );
291        m_RegionChooser.signal_region_to_be_changed().connect(
292            region_to_be_changed_signal.make_slot());
293        m_RegionChooser.signal_region_changed_signal().connect(
294            region_changed_signal.make_slot());
295    
296      file = 0;      file = 0;
297      file_is_changed = false;      file_is_changed = false;
298    
299      show_all_children();      show_all_children();
300    
301        // start with a new gig file by default
302        on_action_file_new();
303  }  }
304    
305  MainWindow::~MainWindow()  MainWindow::~MainWindow()
# Line 407  bool MainWindow::close_confirmation_dial Line 454  bool MainWindow::close_confirmation_dial
454                                   Glib::filename_display_basename(filename).c_str());                                   Glib::filename_display_basename(filename).c_str());
455      Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);      Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
456      g_free(msg);      g_free(msg);
457    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6) || GTKMM_MAJOR_VERSION > 2
458      dialog.set_secondary_text(_("If you close without saving, your changes will be lost."));      dialog.set_secondary_text(_("If you close without saving, your changes will be lost."));
459    #endif
460      dialog.add_button(_("Close _Without Saving"), Gtk::RESPONSE_NO);      dialog.add_button(_("Close _Without Saving"), Gtk::RESPONSE_NO);
461      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
462      dialog.add_button(file_has_name ? Gtk::Stock::SAVE : Gtk::Stock::SAVE_AS, Gtk::RESPONSE_YES);      dialog.add_button(file_has_name ? Gtk::Stock::SAVE : Gtk::Stock::SAVE_AS, Gtk::RESPONSE_YES);
463      dialog.set_default_response(Gtk::RESPONSE_YES);      dialog.set_default_response(Gtk::RESPONSE_YES);
464      int response = dialog.run();      int response = dialog.run();
465        dialog.hide();
466      if (response == Gtk::RESPONSE_YES) return file_save();      if (response == Gtk::RESPONSE_YES) return file_save();
467      return response != Gtk::RESPONSE_CANCEL;      return response != Gtk::RESPONSE_CANCEL;
468  }  }
# Line 434  void MainWindow::on_action_file_open() Line 484  void MainWindow::on_action_file_open()
484      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
485          std::string filename = dialog.get_filename();          std::string filename = dialog.get_filename();
486          printf("filename=%s\n", filename.c_str());          printf("filename=%s\n", filename.c_str());
         __clear();  
487          printf("on_action_file_open self=%x\n", Glib::Thread::self());          printf("on_action_file_open self=%x\n", Glib::Thread::self());
488          load_file(filename.c_str());          load_file(filename.c_str());
489          current_dir = Glib::path_get_dirname(filename);          current_dir = Glib::path_get_dirname(filename);
# Line 443  void MainWindow::on_action_file_open() Line 492  void MainWindow::on_action_file_open()
492    
493  void MainWindow::load_file(const char* name)  void MainWindow::load_file(const char* name)
494  {  {
495        __clear();
496      load_dialog = new LoadDialog("Loading...", *this);      load_dialog = new LoadDialog("Loading...", *this);
497      load_dialog->show_all();      load_dialog->show_all();
498      loader = new Loader(strdup(name));      loader = new Loader(strdup(name));
# Line 460  void MainWindow::load_instrument(gig::In Line 510  void MainWindow::load_instrument(gig::In
510          msg.run();          msg.run();
511          Gtk::Main::quit();          Gtk::Main::quit();
512      }      }
513        // clear all GUI elements
514        __clear();
515        // load the instrument
516      gig::File* pFile = (gig::File*) instr->GetParent();      gig::File* pFile = (gig::File*) instr->GetParent();
517      load_gig(pFile, 0 /*file name*/);      load_gig(pFile, 0 /*file name*/);
518      //TODO: automatically select the given instrument      //TODO: automatically select the given instrument
# Line 483  void MainWindow::on_action_file_save() Line 536  void MainWindow::on_action_file_save()
536      file_save();      file_save();
537  }  }
538    
539  bool MainWindow::file_save()  bool MainWindow::check_if_savable()
540  {  {
541      if (!file) return false;      if (!file) return false;
542    
543        if (!file->GetFirstSample()) {
544            Gtk::MessageDialog(*this, _("The file could not be saved "
545                                        "because it contains no samples"),
546                               false, Gtk::MESSAGE_ERROR).run();
547            return false;
548        }
549    
550        for (gig::Instrument* instrument = file->GetFirstInstrument() ; instrument ;
551             instrument = file->GetNextInstrument()) {
552            if (!instrument->GetFirstRegion()) {
553                Gtk::MessageDialog(*this, _("The file could not be saved "
554                                            "because there are instruments "
555                                            "that have no regions"),
556                                   false, Gtk::MESSAGE_ERROR).run();
557                return false;
558            }
559        }
560        return true;
561    }
562    
563    bool MainWindow::file_save()
564    {
565        if (!check_if_savable()) return false;
566      if (!file_has_name) return file_save_as();      if (!file_has_name) return file_save_as();
567    
568      std::cout << "Saving file\n" << std::flush;      std::cout << "Saving file\n" << std::flush;
569        file_structure_to_be_changed_signal.emit(this->file);
570      try {      try {
571          file->Save();          file->Save();
572          if (file_is_changed) {          if (file_is_changed) {
# Line 496  bool MainWindow::file_save() Line 574  bool MainWindow::file_save()
574              file_is_changed = false;              file_is_changed = false;
575          }          }
576      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
577            file_structure_changed_signal.emit(this->file);
578          Glib::ustring txt = "Could not save file: " + e.Message;          Glib::ustring txt = "Could not save file: " + e.Message;
579          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
580          msg.run();          msg.run();
# Line 503  bool MainWindow::file_save() Line 582  bool MainWindow::file_save()
582      }      }
583      std::cout << "Saving file done\n" << std::flush;      std::cout << "Saving file done\n" << std::flush;
584      __import_queued_samples();      __import_queued_samples();
585        file_structure_changed_signal.emit(this->file);
586      return true;      return true;
587  }  }
588    
589  void MainWindow::on_action_file_save_as()  void MainWindow::on_action_file_save_as()
590  {  {
591        if (!check_if_savable()) return;
592      file_save_as();      file_save_as();
593  }  }
594    
595  bool MainWindow::file_save_as()  bool MainWindow::file_save_as()
596  {  {
     if (!file) return false;  
597      Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);      Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);
598      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
599      dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
# Line 535  bool MainWindow::file_save_as() Line 615  bool MainWindow::file_save_as()
615      dialog.set_current_name(Glib::filename_display_basename(filename));      dialog.set_current_name(Glib::filename_display_basename(filename));
616    
617      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
618            file_structure_to_be_changed_signal.emit(this->file);
619          try {          try {
620              std::string filename = dialog.get_filename();              std::string filename = dialog.get_filename();
621              if (!Glib::str_has_suffix(filename, ".gig")) {              if (!Glib::str_has_suffix(filename, ".gig")) {
# Line 548  bool MainWindow::file_save_as() Line 629  bool MainWindow::file_save_as()
629              file_has_name = true;              file_has_name = true;
630              file_is_changed = false;              file_is_changed = false;
631          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
632                file_structure_changed_signal.emit(this->file);
633              Glib::ustring txt = "Could not save file: " + e.Message;              Glib::ustring txt = "Could not save file: " + e.Message;
634              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
635              msg.run();              msg.run();
636              return false;              return false;
637          }          }
638          __import_queued_samples();          __import_queued_samples();
639            file_structure_changed_signal.emit(this->file);
640          return true;          return true;
641      }      }
642      return false;      return false;
# Line 576  void MainWindow::__import_queued_samples Line 659  void MainWindow::__import_queued_samples
659              int bitdepth;              int bitdepth;
660              switch (info.format & 0xff) {              switch (info.format & 0xff) {
661                  case SF_FORMAT_PCM_S8:                  case SF_FORMAT_PCM_S8:
                     bitdepth = 16; // we simply convert to 16 bit for now  
                     break;  
662                  case SF_FORMAT_PCM_16:                  case SF_FORMAT_PCM_16:
663                    case SF_FORMAT_PCM_U8:
664                      bitdepth = 16;                      bitdepth = 16;
665                      break;                      break;
666                  case SF_FORMAT_PCM_24:                  case SF_FORMAT_PCM_24:
                     bitdepth = 32; // we simply convert to 32 bit for now  
                     break;  
667                  case SF_FORMAT_PCM_32:                  case SF_FORMAT_PCM_32:
                     bitdepth = 32;  
                     break;  
                 case SF_FORMAT_PCM_U8:  
                     bitdepth = 16; // we simply convert to 16 bit for now  
                     break;  
668                  case SF_FORMAT_FLOAT:                  case SF_FORMAT_FLOAT:
                     bitdepth = 32;  
                     break;  
669                  case SF_FORMAT_DOUBLE:                  case SF_FORMAT_DOUBLE:
670                      bitdepth = 32; // I guess we will always truncate this to 32 bit                      bitdepth = 24;
671                      break;                      break;
672                  default:                  default:
673                      sf_close(hFile); // close sound file                      sf_close(hFile); // close sound file
674                      throw std::string("format not supported"); // unsupported subformat (yet?)                      throw std::string("format not supported"); // unsupported subformat (yet?)
675              }              }
676              // allocate appropriate copy buffer (TODO: for now we copy  
677              // it in one piece, might be tough for very long samples)              const int bufsize = 10000;
             // and copy sample data into buffer  
             int8_t* buffer = NULL;  
678              switch (bitdepth) {              switch (bitdepth) {
679                  case 16:                  case 16: {
680                      buffer = new int8_t[2 * info.channels * info.frames];                      short* buffer = new short[bufsize * info.channels];
681                      // libsndfile does the conversion for us (if needed)                      sf_count_t cnt = info.frames;
682                      sf_readf_short(hFile, (short*) buffer, info.frames);                      while (cnt) {
683                            // libsndfile does the conversion for us (if needed)
684                            int n = sf_readf_short(hFile, buffer, bufsize);
685                            // write from buffer directly (physically) into .gig file
686                            iter->gig_sample->Write(buffer, n);
687                            cnt -= n;
688                        }
689                        delete[] buffer;
690                      break;                      break;
691                  case 32:                  }
692                      buffer = new int8_t[4 * info.channels * info.frames];                  case 24: {
693                      // libsndfile does the conversion for us (if needed)                      int* srcbuf = new int[bufsize * info.channels];
694                      sf_readf_int(hFile, (int*) buffer, info.frames);                      uint8_t* dstbuf = new uint8_t[bufsize * 3 * info.channels];
695                        sf_count_t cnt = info.frames;
696                        while (cnt) {
697                            // libsndfile returns 32 bits, convert to 24
698                            int n = sf_readf_int(hFile, srcbuf, bufsize);
699                            int j = 0;
700                            for (int i = 0 ; i < n * info.channels ; i++) {
701                                dstbuf[j++] = srcbuf[i] >> 8;
702                                dstbuf[j++] = srcbuf[i] >> 16;
703                                dstbuf[j++] = srcbuf[i] >> 24;
704                            }
705                            // write from buffer directly (physically) into .gig file
706                            iter->gig_sample->Write(dstbuf, n);
707                            cnt -= n;
708                        }
709                        delete[] srcbuf;
710                        delete[] dstbuf;
711                      break;                      break;
712                    }
713              }              }
             // write from buffer directly (physically) into .gig file  
             (*iter).gig_sample->Write(buffer, info.frames);  
714              // cleanup              // cleanup
715              sf_close(hFile);              sf_close(hFile);
             delete[] buffer;  
716              // on success we remove the sample from the import queue,              // on success we remove the sample from the import queue,
717              // otherwise keep it, maybe it works the next time ?              // otherwise keep it, maybe it works the next time ?
718              std::list<SampleImportItem>::iterator cur = iter;              std::list<SampleImportItem>::iterator cur = iter;
# Line 712  void PropDialog::set_info(DLS::Info* inf Line 804  void PropDialog::set_info(DLS::Info* inf
804      entry[15].set_text(info->Subject);      entry[15].set_text(info->Subject);
805  }  }
806    
807    void InstrumentProps::add_prop(BoolEntry& boolentry)
808    {
809        table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,
810                     Gtk::FILL, Gtk::SHRINK);
811        rowno++;
812        boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());
813    }
814    
815    void InstrumentProps::add_prop(BoolEntryPlus6& boolentry)
816    {
817        table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,
818                     Gtk::FILL, Gtk::SHRINK);
819        rowno++;
820        boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());
821    }
822    
823  void InstrumentProps::add_prop(LabelWidget& prop)  void InstrumentProps::add_prop(LabelWidget& prop)
824  {  {
825      table.attach(prop.label, 0, 1, rowno, rowno + 1,      table.attach(prop.label, 0, 1, rowno, rowno + 1,
# Line 726  InstrumentProps::InstrumentProps() Line 834  InstrumentProps::InstrumentProps()
834      : table(2,1),      : table(2,1),
835        quitButton(Gtk::Stock::CLOSE),        quitButton(Gtk::Stock::CLOSE),
836        eName("Name"),        eName("Name"),
837        eIsDrum("IsDrum"),        eIsDrum("Is drum"),
838        eMIDIBank("MIDIBank", 0, 16383),        eMIDIBank("MIDI bank", 0, 16383),
839        eMIDIProgram("MIDIProgram"),        eMIDIProgram("MIDI program"),
840        eAttenuation("Attenuation", 0, 96, 0, 1),        eAttenuation("Attenuation", 0, 96, 0, 1),
841        eGainPlus6("Gain +6dB", eAttenuation, -6),        eGainPlus6("Gain +6dB", eAttenuation, -6),
842        eEffectSend("EffectSend", 0, 65535),        eEffectSend("Effect send", 0, 65535),
843        eFineTune("FineTune", -8400, 8400),        eFineTune("Fine tune", -8400, 8400),
844        ePitchbendRange("PitchbendRange", 0, 12),        ePitchbendRange("Pitchbend range", 0, 12),
845        ePianoReleaseMode("PianoReleaseMode"),        ePianoReleaseMode("Piano release mode"),
846        eDimensionKeyRangeLow("DimensionKeyRangeLow"),        eDimensionKeyRangeLow("Dimension key range low"),
847        eDimensionKeyRangeHigh("DimensionKeyRangeHigh")        eDimensionKeyRangeHigh("Dimension key range high")
848  {  {
849      set_title("Instrument properties");      set_title("Instrument properties");
850    
# Line 1027  void MainWindow::on_action_add_sample() Line 1135  void MainWindow::on_action_add_sample()
1135      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1136      dialog.set_select_multiple(true);      dialog.set_select_multiple(true);
1137      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile
1138      const char* supportedFileTypes[] = {      const char* const supportedFileTypes[] = {
1139          "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",          "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",
1140          "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",          "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",
1141          "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",          "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",
# Line 1057  void MainWindow::on_action_add_sample() Line 1165  void MainWindow::on_action_add_sample()
1165                  int bitdepth;                  int bitdepth;
1166                  switch (info.format & 0xff) {                  switch (info.format & 0xff) {
1167                      case SF_FORMAT_PCM_S8:                      case SF_FORMAT_PCM_S8:
                         bitdepth = 16; // we simply convert to 16 bit for now  
                         break;  
1168                      case SF_FORMAT_PCM_16:                      case SF_FORMAT_PCM_16:
1169                        case SF_FORMAT_PCM_U8:
1170                          bitdepth = 16;                          bitdepth = 16;
1171                          break;                          break;
1172                      case SF_FORMAT_PCM_24:                      case SF_FORMAT_PCM_24:
                         bitdepth = 32; // we simply convert to 32 bit for now  
                         break;  
1173                      case SF_FORMAT_PCM_32:                      case SF_FORMAT_PCM_32:
                         bitdepth = 32;  
                         break;  
                     case SF_FORMAT_PCM_U8:  
                         bitdepth = 16; // we simply convert to 16 bit for now  
                         break;  
1174                      case SF_FORMAT_FLOAT:                      case SF_FORMAT_FLOAT:
                         bitdepth = 32;  
                         break;  
1175                      case SF_FORMAT_DOUBLE:                      case SF_FORMAT_DOUBLE:
1176                          bitdepth = 32; // I guess we will always truncate this to 32 bit                          bitdepth = 24;
1177                          break;                          break;
1178                      default:                      default:
1179                          sf_close(hFile); // close sound file                          sf_close(hFile); // close sound file
# Line 1084  void MainWindow::on_action_add_sample() Line 1182  void MainWindow::on_action_add_sample()
1182                  // add a new sample to the .gig file                  // add a new sample to the .gig file
1183                  gig::Sample* sample = file->AddSample();                  gig::Sample* sample = file->AddSample();
1184                  // file name without path                  // file name without path
1185                  sample->pInfo->Name = (*iter).substr((*iter).rfind('/') + 1).raw();                  Glib::ustring filename = Glib::filename_display_basename(*iter);
1186                    // remove file extension if there is one
1187                    for (int i = 0; supportedFileTypes[i]; i++) {
1188                        if (Glib::str_has_suffix(filename, supportedFileTypes[i] + 1)) {
1189                            filename.erase(filename.length() - strlen(supportedFileTypes[i] + 1));
1190                            break;
1191                        }
1192                    }
1193                    sample->pInfo->Name = filename;
1194                  sample->Channels = info.channels;                  sample->Channels = info.channels;
1195                  sample->BitDepth = bitdepth;                  sample->BitDepth = bitdepth;
1196                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;
1197                  sample->SamplesPerSecond = info.samplerate;                  sample->SamplesPerSecond = info.samplerate;
1198                    sample->AverageBytesPerSecond = sample->FrameSize * sample->SamplesPerSecond;
1199                    sample->BlockAlign = sample->FrameSize;
1200                    sample->SamplesTotal = info.frames;
1201    
1202                    SF_INSTRUMENT instrument;
1203                    if (sf_command(hFile, SFC_GET_INSTRUMENT,
1204                                   &instrument, sizeof(instrument)) != SF_FALSE)
1205                    {
1206                        sample->MIDIUnityNote = instrument.basenote;
1207    
1208    #if HAVE_SF_INSTRUMENT_LOOPS
1209                        if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {
1210                            sample->Loops = 1;
1211    
1212                            switch (instrument.loops[0].mode) {
1213                            case SF_LOOP_FORWARD:
1214                                sample->LoopType = gig::loop_type_normal;
1215                                break;
1216                            case SF_LOOP_BACKWARD:
1217                                sample->LoopType = gig::loop_type_backward;
1218                                break;
1219                            case SF_LOOP_ALTERNATING:
1220                                sample->LoopType = gig::loop_type_bidirectional;
1221                                break;
1222                            }
1223                            sample->LoopStart = instrument.loops[0].start;
1224                            sample->LoopEnd = instrument.loops[0].end;
1225                            sample->LoopPlayCount = instrument.loops[0].count;
1226                            sample->LoopSize = sample->LoopEnd - sample->LoopStart + 1;
1227                        }
1228    #endif
1229                    }
1230    
1231                  // schedule resizing the sample (which will be done                  // schedule resizing the sample (which will be done
1232                  // physically when File::Save() is called)                  // physically when File::Save() is called)
1233                  sample->Resize(info.frames);                  sample->Resize(info.frames);
# Line 1104  void MainWindow::on_action_add_sample() Line 1243  void MainWindow::on_action_add_sample()
1243                  Gtk::TreeModel::iterator iterSample =                  Gtk::TreeModel::iterator iterSample =
1244                      m_refSamplesTreeModel->append(row.children());                      m_refSamplesTreeModel->append(row.children());
1245                  Gtk::TreeModel::Row rowSample = *iterSample;                  Gtk::TreeModel::Row rowSample = *iterSample;
1246                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();                  rowSample[m_SamplesModel.m_col_name]   = filename;
1247                  rowSample[m_SamplesModel.m_col_sample] = sample;                  rowSample[m_SamplesModel.m_col_sample] = sample;
1248                  rowSample[m_SamplesModel.m_col_group]  = NULL;                  rowSample[m_SamplesModel.m_col_group]  = NULL;
1249                  // close sound file                  // close sound file
# Line 1143  void MainWindow::on_action_remove_sample Line 1282  void MainWindow::on_action_remove_sample
1282                       pSample; pSample = group->GetNextSample()) {                       pSample; pSample = group->GetNextSample()) {
1283                      members.push_back(pSample);                      members.push_back(pSample);
1284                  }                  }
1285                    // notify everybody that we're going to remove these samples
1286                    samples_to_be_removed_signal.emit(members);
1287                  // delete the group in the .gig file including the                  // delete the group in the .gig file including the
1288                  // samples that belong to the group                  // samples that belong to the group
1289                  file->DeleteGroup(group);                  file->DeleteGroup(group);
1290                    // notify that we're done with removal
1291                    samples_removed_signal.emit();
1292                  // if sample(s) were just previously added, remove                  // if sample(s) were just previously added, remove
1293                  // them from the import queue                  // them from the import queue
1294                  for (std::list<gig::Sample*>::iterator member = members.begin();                  for (std::list<gig::Sample*>::iterator member = members.begin();
# Line 1162  void MainWindow::on_action_remove_sample Line 1305  void MainWindow::on_action_remove_sample
1305                  }                  }
1306                  file_changed();                  file_changed();
1307              } else if (sample) {              } else if (sample) {
1308                    // notify everybody that we're going to remove this sample
1309                    std::list<gig::Sample*> lsamples;
1310                    lsamples.push_back(sample);
1311                    samples_to_be_removed_signal.emit(lsamples);
1312                  // remove sample from the .gig file                  // remove sample from the .gig file
1313                  file->DeleteSample(sample);                  file->DeleteSample(sample);
1314                    // notify that we're done with removal
1315                    samples_removed_signal.emit();
1316                  // if sample was just previously added, remove it from                  // if sample was just previously added, remove it from
1317                  // the import queue                  // the import queue
1318                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();
# Line 1175  void MainWindow::on_action_remove_sample Line 1324  void MainWindow::on_action_remove_sample
1324                          break;                          break;
1325                      }                      }
1326                  }                  }
1327                    dimreg_changed();
1328                  file_changed();                  file_changed();
1329              }              }
1330              // remove respective row(s) from samples tree view              // remove respective row(s) from samples tree view
1331              m_refSamplesTreeModel->erase(it);              m_refSamplesTreeModel->erase(it);
1332          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1333                // pretend we're done with removal (i.e. to avoid dead locks)
1334                samples_removed_signal.emit();
1335                // show error message
1336              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);
1337              msg.run();              msg.run();
1338          }          }
1339      }      }
1340  }  }
1341    
1342    // For some reason drag_data_get gets called two times for each
1343    // drag'n'drop (at least when target is an Entry). This work-around
1344    // makes sure the code in drag_data_get and drop_drag_data_received is
1345    // only executed once, as drag_begin only gets called once.
1346    void MainWindow::on_sample_treeview_drag_begin(const Glib::RefPtr<Gdk::DragContext>& context)
1347    {
1348        first_call_to_drag_data_get = true;
1349    }
1350    
1351  void MainWindow::on_sample_treeview_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&,  void MainWindow::on_sample_treeview_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&,
1352                                                    Gtk::SelectionData& selection_data, guint, guint)                                                    Gtk::SelectionData& selection_data, guint, guint)
1353  {  {
1354        if (!first_call_to_drag_data_get) return;
1355        first_call_to_drag_data_get = false;
1356    
1357      // get selected sample      // get selected sample
1358      gig::Sample* sample = NULL;      gig::Sample* sample = NULL;
1359      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();
# Line 1206  void MainWindow::on_sample_label_drop_dr Line 1371  void MainWindow::on_sample_label_drop_dr
1371      const Glib::RefPtr<Gdk::DragContext>& context, int, int,      const Glib::RefPtr<Gdk::DragContext>& context, int, int,
1372      const Gtk::SelectionData& selection_data, guint, guint time)      const Gtk::SelectionData& selection_data, guint, guint time)
1373  {  {
     gig::DimensionRegion* dimregion = m_DimRegionChooser.get_dimregion();  
1374      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());
1375    
1376      if (sample && dimregion && selection_data.get_length() == sizeof(gig::Sample*)) {      if (sample && selection_data.get_length() == sizeof(gig::Sample*)) {
1377          if (sample != dimregion->pSample) {          std::cout << "Drop received sample \"" <<
1378              dimregion->pSample = sample;              sample->pInfo->Name << "\"" << std::endl;
1379              dimreg_edit.wSample->set_text(dimregion->pSample->pInfo->Name.c_str());          // drop success
1380              std::cout << "Drop received sample \"" <<          context->drop_reply(true, time);
1381                  dimregion->pSample->pInfo->Name.c_str() << "\"" << std::endl;  
1382              // drop success          //TODO: we should better move most of the following code to DimRegionEdit::set_sample()
1383              context->drop_reply(true, time);  
1384              file_changed();          // notify everybody that we're going to alter the region
1385              return;          gig::Region* region = m_RegionChooser.get_region();
1386            region_to_be_changed_signal.emit(region);
1387    
1388            // find the samplechannel dimension
1389            gig::dimension_def_t* stereo_dimension = 0;
1390            for (int i = 0 ; i < region->Dimensions ; i++) {
1391                if (region->pDimensionDefinitions[i].dimension ==
1392                    gig::dimension_samplechannel) {
1393                    stereo_dimension = &region->pDimensionDefinitions[i];
1394                    break;
1395                }
1396            }
1397            bool channels_changed = false;
1398            if (sample->Channels == 1 && stereo_dimension) {
1399                // remove the samplechannel dimension
1400                region->DeleteDimension(stereo_dimension);
1401                channels_changed = true;
1402                region_changed();
1403            }
1404            dimreg_edit.set_sample(sample);
1405    
1406            if (sample->Channels == 2 && !stereo_dimension) {
1407                // add samplechannel dimension
1408                gig::dimension_def_t dim;
1409                dim.dimension = gig::dimension_samplechannel;
1410                dim.bits = 1;
1411                dim.zones = 2;
1412                region->AddDimension(&dim);
1413                channels_changed = true;
1414                region_changed();
1415            }
1416            if (channels_changed) {
1417                // unmap all samples with wrong number of channels
1418                // TODO: maybe there should be a warning dialog for this
1419                for (int i = 0 ; i < region->DimensionRegions ; i++) {
1420                    gig::DimensionRegion* d = region->pDimensionRegions[i];
1421                    if (d->pSample && d->pSample->Channels != sample->Channels) {
1422                        gig::Sample* oldref = d->pSample;
1423                        d->pSample = NULL;
1424                        sample_ref_changed_signal.emit(oldref, NULL);
1425                    }
1426                }
1427          }          }
1428    
1429            // notify we're done with altering
1430            region_changed_signal.emit(region);
1431    
1432            return;
1433      }      }
1434      // drop failed      // drop failed
1435      context->drop_reply(false, time);      context->drop_reply(false, time);
# Line 1258  void MainWindow::instrument_name_changed Line 1468  void MainWindow::instrument_name_changed
1468          file_changed();          file_changed();
1469      }      }
1470  }  }
1471    
1472    sigc::signal<void, gig::File*> MainWindow::signal_file_structure_to_be_changed() {
1473        return file_structure_to_be_changed_signal;
1474    }
1475    
1476    sigc::signal<void, gig::File*> MainWindow::signal_file_structure_changed() {
1477        return file_structure_changed_signal;
1478    }
1479    
1480    sigc::signal<void, std::list<gig::Sample*> > MainWindow::signal_samples_to_be_removed() {
1481        return samples_to_be_removed_signal;
1482    }
1483    
1484    sigc::signal<void> MainWindow::signal_samples_removed() {
1485        return samples_removed_signal;
1486    }
1487    
1488    sigc::signal<void, gig::Region*> MainWindow::signal_region_to_be_changed() {
1489        return region_to_be_changed_signal;
1490    }
1491    
1492    sigc::signal<void, gig::Region*> MainWindow::signal_region_changed() {
1493        return region_changed_signal;
1494    }
1495    
1496    sigc::signal<void, gig::Sample*/*old*/, gig::Sample*/*new*/> MainWindow::signal_sample_ref_changed() {
1497        return sample_ref_changed_signal;
1498    }
1499    
1500    sigc::signal<void, gig::DimensionRegion*> MainWindow::signal_dimreg_to_be_changed() {
1501        return dimreg_to_be_changed_signal;
1502    }
1503    
1504    sigc::signal<void, gig::DimensionRegion*> MainWindow::signal_dimreg_changed() {
1505        return dimreg_changed_signal;
1506    }

Legend:
Removed from v.1261  
changed lines
  Added in v.1328

  ViewVC Help
Powered by ViewVC