~ubuntu-branches/ubuntu/karmic/mhwaveedit/karmic

« back to all changes in this revision

Viewing changes to src/filetypes.c

  • Committer: Bazaar Package Importer
  • Author(s): Free Ekanayaka
  • Date: 2008-01-08 22:20:37 UTC
  • mfrom: (2.1.6 hardy)
  • Revision ID: james.westby@ubuntu.com-20080108222037-tsazhckl5vmc8yih
Tags: 1.4.14-2
Added desktop file (Closes: #457849), thanks to Marco Rodrigues

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
};
59
59
 
60
60
static GList *file_types = NULL;
 
61
static struct file_type *raw_type,*mplayer_type;
61
62
 
62
63
static gboolean wav_check(gchar *filename);
63
64
static Chunk *wav_load(gchar *filename, int dither_mode, StatusBar *bar);
64
 
static gboolean wav_save(Chunk *chunk, gchar *filename, gpointer settings,
65
 
                         struct file_type *type, int dither_mode, 
66
 
                         StatusBar *bar,gboolean *fatal);
 
65
static gint wav_save(Chunk *chunk, gchar *filename, gpointer settings,
 
66
                     struct file_type *type, int dither_mode, 
 
67
                     StatusBar *bar,gboolean *fatal);
67
68
 
68
69
#ifdef HAVE_LIBSNDFILE
69
70
static gboolean sndfile_check(gchar *filename);
70
71
static Chunk *sndfile_load(gchar *filename, int dither_mode, StatusBar *bar);
71
 
static gboolean sndfile_save(Chunk *chunk, gchar *filename, gpointer settings,
72
 
                             struct file_type *type, int dither_mode, 
73
 
                             StatusBar *bar, gboolean *fatal);
 
72
static gint sndfile_save(Chunk *chunk, gchar *filename, gpointer settings,
 
73
                         struct file_type *type, int dither_mode, 
 
74
                         StatusBar *bar, gboolean *fatal);
74
75
static gboolean sndfile_save_main(Chunk *chunk, gchar *filename, 
75
76
                                  int format, int dither_mode, StatusBar *bar,
76
77
                                  gboolean *fatal);
77
78
#endif
78
79
 
79
80
static Chunk *raw_load(gchar *filename, int dither_mode, StatusBar *bar);
80
 
static gboolean raw_save(Chunk *chunk, gchar *filename, gpointer settings,
81
 
                         struct file_type *type, int dither_mode,
82
 
                         StatusBar *bar, gboolean *fatal);
 
81
static gint raw_save(Chunk *chunk, gchar *filename, gpointer settings,
 
82
                     struct file_type *type, int dither_mode,
 
83
                     StatusBar *bar, gboolean *fatal);
83
84
 
84
85
static Chunk *ogg_load(gchar *filename, int dither_mode, StatusBar *bar);
85
 
static gboolean ogg_save(Chunk *chunk, gchar *filename, gpointer settings,
86
 
                         struct file_type *type,
87
 
                         int dither_mode, StatusBar *bar, gboolean *fatal);
 
86
static gint ogg_save(Chunk *chunk, gchar *filename, gpointer settings,
 
87
                     struct file_type *type,
 
88
                     int dither_mode, StatusBar *bar, gboolean *fatal);
88
89
 
89
90
 
90
91
static gpointer mp3_get_settings(void);
91
92
static Chunk *mp3_load(gchar *filename, int dither_mode, StatusBar *bar);
92
 
static gboolean mp3_save(Chunk *chunk, gchar *filename, gpointer settings,
93
 
                         struct file_type *type,
94
 
                         int dither_mode, StatusBar *bar, gboolean *fatal);
 
93
static gint mp3_save(Chunk *chunk, gchar *filename, gpointer settings,
 
94
                     struct file_type *type,
 
95
                     int dither_mode, StatusBar *bar, gboolean *fatal);
95
96
 
96
97
static Chunk *try_mplayer(gchar *filename, int dither_mode, StatusBar *bar);
97
98
 
121
122
(gchar *name, gchar *ext, gboolean lossy,
122
123
 gboolean (*typecheck)(gchar *filename), 
123
124
 Chunk *(*load)(gchar *filename, int dither_mode, StatusBar *bar),
124
 
 gboolean (*save)(Chunk *chunk, gchar *filename,gpointer settings,
125
 
                  struct file_type *type,int dither_mode,
126
 
                  StatusBar *bar,gboolean *fatal),
 
125
 gint (*save)(Chunk *chunk, gchar *filename,gpointer settings,
 
126
              struct file_type *type,int dither_mode,
 
127
              StatusBar *bar,gboolean *fatal),
127
128
 int extra_data)
128
129
{
129
130
     struct file_type *t;
176
177
            t->get_settings = mp3_get_settings;
177
178
            t->free_settings = g_free;
178
179
     }
179
 
     register_file_type(_("Raw PCM data"), ".raw", FALSE,NULL, raw_load, 
180
 
                        raw_save, 0);
 
180
     raw_type = register_file_type(_("Raw PCM data"), ".raw", FALSE,NULL, 
 
181
                                   raw_load, raw_save, 0);
 
182
     mplayer_type = register_file_type(_("Open with MPlayer"), NULL,TRUE,NULL,
 
183
                                       try_mplayer, NULL, 0);
181
184
}
182
185
 
183
186
guint fileformat_count(void)
242
245
     }
243
246
     /* Try mplayer if available */
244
247
     chunk = try_mplayer(filename,dither_mode,bar);
245
 
     if (chunk != NULL) return chunk;
 
248
     if (chunk != NULL) {
 
249
          *format = mplayer_type;
 
250
          return chunk;
 
251
     }
246
252
     /* Use the raw loader */
 
253
     *format = raw_type;
247
254
     return raw_load(filename,dither_mode,bar);
248
255
}
249
256
 
253
260
     Chunk *chunk;
254
261
     gchar *c;
255
262
     EFILE *f;
256
 
     struct file_type *ft;
 
263
     struct file_type *ft = NULL;
257
264
 
258
265
     /* First, see if the file exists */
259
266
     if (!file_exists(filename)) {
525
532
static gboolean wav_save(Chunk *chunk, char *filename, gpointer settings,
526
533
                         struct file_type *type, int dither_mode, 
527
534
                         StatusBar *bar, gboolean *fatal)
528
 
{
 
535
{    
 
536
     Chunk *c;
529
537
     EFILE *f;
530
538
     Datasource *ds;
531
539
     DataPart *dp;
532
 
     Dataformat *fmt;
 
540
     Dataformat *fmt,cfmt;
 
541
     gboolean b,q;
 
542
 
533
543
     fmt = &(chunk->format);
 
544
     
534
545
 
535
546
     /* Check if the format is OK */     
536
547
 
543
554
     }
544
555
#endif
545
556
 
 
557
     if (fmt->type == DATAFORMAT_PCM) {
 
558
          /* Check that the sign and endian-ness is correct */
 
559
          if (fmt->samplesize == 1) q = FALSE;
 
560
          else q = TRUE;
 
561
          if (XOR(fmt->sign,q) || fmt->bigendian) {
 
562
               memcpy(&cfmt,fmt,sizeof(cfmt));
 
563
               cfmt.sign = q;
 
564
               cfmt.bigendian = FALSE;
 
565
               c = chunk_convert(chunk,&cfmt,DITHER_UNSPEC,bar);
 
566
               b = wav_save(c,filename,settings,type,dither_mode,bar,fatal);
 
567
               gtk_object_sink(GTK_OBJECT(c));
 
568
               return b;
 
569
          }
 
570
     }
 
571
 
 
572
     
546
573
     if (fmt->type == DATAFORMAT_PCM && fmt->samplesize==1 && fmt->sign) {
547
 
          user_error(_("8-bit wav-files must be in unsigned format!"));
548
 
          return TRUE;
 
574
          /* user_error(_("8-bit wav-files must be in unsigned format!")); */
 
575
          g_assert_not_reached();
549
576
     }
550
577
     if (fmt->type == DATAFORMAT_PCM && fmt->samplesize>1 && !fmt->sign) {
551
 
          user_error(_("16/24/32-bit wav-files must be in signed format!"));
552
 
          return TRUE;
 
578
          /*user_error(_("16/24/32-bit wav-files must be in signed format!"));
 
579
          */
 
580
          g_assert_not_reached();
553
581
     }    
554
582
     if (fmt->type == DATAFORMAT_PCM && fmt->bigendian == TRUE) {
555
 
          user_error(_("wav files must be in little endian format!"));
556
 
          return TRUE;
 
583
          /* user_error(_("wav files must be in little endian format!")); */
 
584
          g_assert_not_reached();
557
585
     }
558
586
 
559
587
     /* Give a warning once if we're saving a file larger than 2GB */
603
631
               e_fclose(f);
604
632
               return TRUE;
605
633
          }
606
 
          if (chunk_dump(chunk,f,FALSE,dither_mode,bar)) {
 
634
          b = chunk_dump(chunk,f,FALSE,dither_mode,bar);
 
635
          if (b) {
607
636
               e_fclose_remove(f);
608
637
               return TRUE;
609
638
          }
610
639
          e_fclose ( f );
 
640
          return FALSE;
611
641
     }    
612
 
     return FALSE;
 
642
     return 0;
613
643
}
614
644
 
615
645
/* RAW */
619
649
     Datasource *ds;
620
650
     Dataformat *fmt;
621
651
     off_t i;
622
 
     fmt = rawdialog_execute(filename);
623
 
     if (!fmt) return NULL;
 
652
     guint offs;
624
653
     i = errdlg_filesize(filename);
625
654
     if (i==-1) return NULL;
 
655
     fmt = rawdialog_execute(filename,i,&offs);
 
656
     if (!fmt) return NULL;
626
657
     ds = (Datasource *)gtk_type_new(datasource_get_type());
627
658
     memcpy(&(ds->format),fmt,sizeof(Dataformat));
628
 
     ds->bytes = i;
629
 
     ds->length = i/fmt->samplebytes;
 
659
     ds->bytes = i-offs;
 
660
     ds->length = (i-offs)/fmt->samplebytes;
630
661
     ds->type = DATASOURCE_VIRTUAL;
631
662
     ds->data.virtual.filename = g_strdup(filename);
632
 
     ds->data.virtual.offset = 0;
 
663
     ds->data.virtual.offset = offs;
633
664
     return chunk_new_from_datasource(ds);
634
665
}
635
666
 
636
 
static gboolean raw_save(Chunk *chunk, gchar *filename, gpointer settings,
 
667
static gint raw_save(Chunk *chunk, gchar *filename, gpointer settings,
637
668
                         struct file_type *type, int dither_mode, 
638
669
                         StatusBar *bar, gboolean *fatal)
639
670
{
640
671
     EFILE *f;
 
672
     gint i;
 
673
 
641
674
     f = e_fopen(filename,EFILE_WRITE);
642
675
     if (!f) return TRUE;
643
 
     if (chunk_dump(chunk,f,IS_BIGENDIAN,dither_mode,bar)) {
644
 
          e_fclose(f);
645
 
          *fatal = TRUE;
646
 
          return TRUE;
647
 
     }
 
676
    
 
677
     i = chunk_dump(chunk,f,IS_BIGENDIAN,dither_mode,bar);
 
678
     if (i < 0) *fatal = TRUE;
648
679
     e_fclose(f);
649
 
     return FALSE;
 
680
     return i;
650
681
}
651
682
 
652
683
/* SNDFILE */
685
716
     f.type = DATAFORMAT_PCM;
686
717
     f.samplerate = info.samplerate;
687
718
     f.channels = info.channels;
 
719
     f.bigendian = IS_BIGENDIAN;
688
720
     /* Fix samplesize parameter */
689
721
     switch (info.format&SF_FORMAT_SUBMASK) {
690
722
     case SF_FORMAT_PCM_U8: f.sign=FALSE;f.samplesize=1;raw_readable=TRUE;break;
721
753
     while (ds->data.sndfile.pos < ds->length) {
722
754
 
723
755
          st = datasource_read_array(ds,ds->data.sndfile.pos,rawbuf_size,
724
 
                                     rawbuf, dither_mode);
 
756
                                     rawbuf, dither_mode, NULL);
725
757
          
726
758
          if (st == 0 || tempfile_write(tmp,rawbuf,st) || 
727
759
              status_bar_progress(bar, st/f.samplebytes)) {
802
834
     SF_INFO info;
803
835
     sample_t *samplebuf;
804
836
     ChunkHandle *ch;
 
837
     off_t clipcount = 0;
805
838
 
806
839
     if (find_nearest_sndfile_format(&(chunk->format),format,&info,filename)) 
807
 
          return TRUE;
 
840
          return -1;
808
841
     
809
842
     s = sf_open(filename, SFM_WRITE, &info);
810
843
     if (!s) {
811
844
          c = g_strdup_printf(_("Failed to open '%s'!"),filename);
812
845
          user_error(c);
813
846
          g_free(c);
814
 
          return TRUE;
 
847
          return -1;
815
848
     }
816
849
 
817
850
     sf_command ( s, SFC_SET_NORM_FLOAT, NULL, SF_TRUE );
820
853
     ch = chunk_open(chunk);
821
854
     if (ch == NULL) {
822
855
          sf_close(s);
823
 
          return TRUE;
 
856
          return -1;
824
857
     }
825
858
 
826
859
     /* We could speed this up a LOT esp. on output to PCM files. */
828
861
 
829
862
     for (i=0; i<chunk->length; i+=n) {
830
863
          /* FIXME: Use chunk_read_array for FP chunks */
831
 
          n = chunk_read_array_fp(ch,i,1024,samplebuf,dither_mode);
 
864
          n = chunk_read_array_fp(ch,i,1024,samplebuf,dither_mode,&clipcount);
832
865
          if (!n) {
833
866
               chunk_close(ch);
834
867
               sf_close(s);
835
868
               g_free(samplebuf);
836
869
               *fatal = TRUE;
837
 
               return TRUE;
 
870
               return -1;
838
871
          }
 
872
          clipcount += unnormalized_count(samplebuf,n*chunk->format.channels);
839
873
          if (sf_writef_sample_t(s,samplebuf,n) != n) {
840
874
               c = g_strdup_printf(_("Failed to write to '%s'!"),filename);
841
875
               user_error(c);
844
878
               sf_close(s);
845
879
               g_free(samplebuf);
846
880
               *fatal = TRUE;
847
 
               return TRUE;  
 
881
               return -1;  
848
882
          }
849
883
          if (status_bar_progress(bar, n*chunk->format.samplebytes)) {
850
884
               chunk_close(ch);
851
885
               sf_close(s);
852
886
               g_free(samplebuf);
853
887
               xunlink(filename);
854
 
               return TRUE;
 
888
               return -1;
855
889
          }
856
890
     }
857
891
     chunk_close(ch);
858
892
     sf_close(s);
859
893
     g_free(samplebuf);
860
 
 
861
 
     return FALSE;
 
894
     return clipwarn(clipcount,TRUE);
862
895
 
863
896
}
864
897
 
865
 
static gboolean sndfile_save(Chunk *chunk, gchar *filename, gpointer settings,
866
 
                             struct file_type *type, int dither_mode, 
867
 
                             StatusBar *bar, gboolean *fatal)
 
898
static gint sndfile_save(Chunk *chunk, gchar *filename, gpointer settings,
 
899
                         struct file_type *type, int dither_mode, 
 
900
                         StatusBar *bar, gboolean *fatal)
868
901
{
869
902
     return sndfile_save_main(chunk,filename,type->extra_data,dither_mode,
870
903
                              bar,fatal);
955
988
     Dataformat fmt;
956
989
     gchar *c,*d;
957
990
     gboolean b;
 
991
     off_t clipcount = 0;
958
992
     xunlink(filename);
959
993
     d = g_strdup_printf("OUTFILE=%s",filename);     
960
994
     if (xputenv(d)) { g_free(d); return TRUE; }
972
1006
                         y->format.samplesize*8, 
973
1007
                         y->format.channels, y->format.samplerate,
974
1008
                         y->format.bigendian?1:0);
975
 
     b = pipe_dialog_send_chunk(y,c,FALSE,dither_mode,bar);
 
1009
     b = pipe_dialog_send_chunk(y,c,FALSE,dither_mode,bar,&clipcount);
976
1010
     g_free(c);     
977
1011
     if (x != NULL) gtk_object_sink(GTK_OBJECT(x));
978
1012
     if (!xunsetenv("OUTFILE")) g_free(d);
979
1013
     if (b || !file_exists(filename)) {
980
1014
          *fatal = TRUE;
981
 
          return TRUE;
 
1015
          return -1;
982
1016
     }
983
 
     return FALSE;
 
1017
     return clipwarn(clipcount,TRUE);
984
1018
}
985
1019
 
986
1020
static struct {
1208
1242
     return (XOR(fmt->samplesize == 1, fmt->sign));
1209
1243
}
1210
1244
 
1211
 
static gboolean mp3_save(Chunk *chunk, gchar *filename, gpointer settings,
1212
 
                         struct file_type *type,
1213
 
                         int dither_mode, StatusBar *bar, gboolean *fatal)
 
1245
static gint mp3_save(Chunk *chunk, gchar *filename, gpointer settings,
 
1246
                     struct file_type *type,
 
1247
                     int dither_mode, StatusBar *bar, gboolean *fatal)
1214
1248
{
1215
1249
     Chunk *x;
1216
1250
     Dataformat fmt;
1217
1251
     gchar *c;
1218
1252
     gboolean b;
 
1253
     off_t clipcount = 0;
1219
1254
     xunlink(filename);
1220
1255
     c = g_strdup_printf("OUTFILE=%s",filename);
1221
 
     if (xputenv(c)) { g_free(c); return TRUE; }
 
1256
     if (xputenv(c)) { g_free(c); return -1; }
1222
1257
     c = g_strdup_printf("LAMEFLAGS=%s",(settings == NULL) ? 
1223
1258
                         "--preset standard" : (gchar *)settings);
1224
 
     if (xputenv(c)) { g_free(c); return TRUE; }
 
1259
     if (xputenv(c)) { g_free(c); return -1; }
1225
1260
     if (wav_regular_format(&(chunk->format)))
1226
1261
         b = pipe_dialog_send_chunk(chunk,
1227
1262
                                    "lame --silent $LAMEFLAGS - "
1228
 
                                    "\"$OUTFILE\"",TRUE,dither_mode,bar);
 
1263
                                    "\"$OUTFILE\"",TRUE,dither_mode,bar,
 
1264
                                    &clipcount);
1229
1265
     else {
1230
1266
          memcpy(&fmt,&(chunk->format),sizeof(Dataformat));
1231
1267
          if (fmt.type == DATAFORMAT_FLOAT || fmt.samplesize == 3) {
1240
1276
          else {
1241
1277
               b = pipe_dialog_send_chunk(x,
1242
1278
                                          "lame --silent --preset standard - "
1243
 
                                          "\"$OUTFILE\"",TRUE,dither_mode,bar);
 
1279
                                          "\"$OUTFILE\"",TRUE,dither_mode,bar,
 
1280
                                          &clipcount);
1244
1281
               gtk_object_sink(GTK_OBJECT(x));
1245
1282
          }
1246
1283
     }
1247
1284
     if (!xunsetenv("OUTFILE")) g_free(c);
1248
1285
     if (b || !file_exists(filename)) {
1249
1286
          *fatal = TRUE;
1250
 
          return TRUE;
 
1287
          return -1;
1251
1288
     }
1252
 
     return FALSE;
 
1289
     return clipwarn(clipcount,TRUE);
1253
1290
}
1254
1291
 
1255
1292
 
1260
1297
     gchar *c,*d;
1261
1298
     char *tempname;
1262
1299
     Chunk *x;
 
1300
     char *argv[] = { "sh", "-c", 
 
1301
                      "mplayer -quiet -noconsolecontrols "
 
1302
                      "-ao \"pcm:file=$OUTFILE\" -vc dummy -vo null "
 
1303
                      "\"$INFILE\"", NULL };
1263
1304
     if (!program_exists("mplayer")) return NULL;
1264
1305
     tempname = get_temp_filename(0);
1265
1306
     c = g_strdup_printf("OUTFILE=%s",tempname);
1272
1313
          g_free(tempname);
1273
1314
          return NULL; 
1274
1315
     }
1275
 
     char *argv[] = { "sh", "-c", 
1276
 
                      "mplayer -quiet -noconsolecontrols "
1277
 
                      "-ao \"pcm:file=$OUTFILE\" -vc dummy -vo null "
1278
 
                      "\"$INFILE\"", NULL };
1279
1316
 
1280
1317
     x = run_decoder(filename,tempname,"sh",argv,dither_mode,bar);
1281
1318