251
251
gboolean datasource_dump(Datasource *ds, off_t position,
252
252
off_t length, EFILE *file, int dither_mode,
253
StatusBar *bar, off_t *clipcount)
259
259
buf = g_malloc(DUMP_BUFSIZE);
260
260
while (length > 0) {
261
261
i = MIN(length*ds->format.samplebytes,DUMP_BUFSIZE);
262
u = datasource_read_array(ds,position,i,buf,dither_mode);
262
u = datasource_read_array(ds,position,i,buf,dither_mode,clipcount);
263
263
if (u==0 || e_fwrite(buf,u,file) || status_bar_progress(bar,u)) {
264
264
datasource_close(ds);
281
281
if (datasource_open(ds)) return TRUE;
283
283
c = g_malloc(sz);
284
if (datasource_read_array(ds,0,sz,c, dither_mode)) {
284
if (datasource_read_array(ds,0,sz,c, dither_mode,NULL)) {
286
286
datasource_close(ds);
386
386
static guint datasource_clone_read_array(Datasource *source, off_t sampleno,
387
387
guint size, gpointer buffer,
388
int dither_mode, off_t *clipcount)
390
390
/* This is not optimized but it's only used in rare cases so the important
391
391
* thing is that it works.*/
405
405
orig_size = size + orig_adjust + source->data.clone->format.samplebytes - 1;
406
406
p = g_malloc(orig_size);
407
407
x = datasource_read_array(source->data.clone, orig_sampleno, orig_size, p,
408
dither_mode,clipcount);
410
410
g_assert(x-orig_adjust >= size);
411
411
memcpy(buffer, p+orig_adjust, size);
513
513
static guint datasource_read_array_main(Datasource *source,
514
514
off_t sampleno, guint size,
515
gpointer buffer, int dither_mode)
515
gpointer buffer, int dither_mode,
520
521
switch (source->type) {
521
522
case DATASOURCE_REAL:
522
523
memcpy(buffer,source->data.real+sampleno*source->format.samplebytes,
547
548
(source,sampleno,size/source->format.samplebytes,buffer);
548
549
case DATASOURCE_REF:
549
550
return datasource_read_array_main(source->data.clone,sampleno,size,
551
buffer,dither_mode,clipcount);
551
552
case DATASOURCE_CLONE:
552
553
return datasource_clone_read_array(source,sampleno,size,buffer,
554
dither_mode,clipcount);
554
555
case DATASOURCE_BYTESWAP:
555
556
u = datasource_read_array_main(source->data.clone,sampleno,size,
557
buffer,dither_mode,clipcount);
557
558
if (u>0) byteswap(buffer,source->format.samplesize,u);
559
560
case DATASOURCE_CONVERT:
561
562
if (source->format.type == DATAFORMAT_FLOAT &&
562
563
source->format.samplesize == sizeof(sample_t))
563
564
return datasource_read_array_fp(source->data.clone,sampleno,u,
564
buffer,dither_mode) *
565
buffer,dither_mode,clipcount) *
565
566
source->format.samplebytes ;
566
567
c = g_malloc(u*sizeof(sample_t)*source->format.channels);
567
568
u = datasource_read_array_fp(source->data.clone, sampleno, u,
568
(gpointer)c,dither_mode);
569
(gpointer)c,dither_mode,clipcount);
571
if (clipcount != NULL)
573
unnormalized_count(c,u*source->format.channels);
570
574
convert_array(c,&dataformat_sample_t,buffer,&(source->format),
571
575
u*source->format.channels,dither_mode);
581
585
guint datasource_read_array(Datasource *source, off_t sampleno, guint size,
582
gpointer buffer, int dither_mode)
586
gpointer buffer, int dither_mode,
585
590
g_assert(source->opencount > 0);
593
598
if (size == 0) return 0;
595
600
return datasource_read_array_main(source,sampleno,size,buffer,
601
dither_mode,clipcount);
599
604
gboolean datasource_read(Datasource *source, off_t sampleno, gpointer buffer,
602
607
return (datasource_read_array(source,sampleno,source->format.samplebytes,
608
buffer,dither_mode,NULL)
604
609
!= source->format.samplebytes);
608
613
guint datasource_read_array_fp(Datasource *source, off_t sampleno,
609
614
guint samples, sample_t *buffer,
615
int dither_mode, off_t *clipcount)
629
634
case DATASOURCE_REF:
630
635
case DATASOURCE_CONVERT:
631
636
return datasource_read_array_fp(source->data.clone,sampleno,
632
samples,buffer,dither_mode);
637
samples,buffer,dither_mode,
634
640
if (source->format.type == DATAFORMAT_FLOAT &&
635
641
source->format.samplesize == sizeof(sample_t))
637
643
return datasource_read_array(source,sampleno,
638
644
samples*source->format.samplebytes,
645
buffer, dither_mode, clipcount)
640
646
/ source->format.samplebytes;
642
648
s = samples * source->format.samplebytes;
644
x = datasource_read_array(source,sampleno,s,p,dither_mode);
650
x = datasource_read_array(source,sampleno,s,p,dither_mode,clipcount);
645
651
g_assert(x==s || x==0);
647
653
convert_array(p,&(source->format),buffer,&dataformat_sample_t,
657
663
gboolean datasource_read_fp(Datasource *ds, off_t sampleno, sample_t *buffer,
660
return (datasource_read_array_fp(ds,sampleno,1,buffer,dither_mode)!=1);
666
return (datasource_read_array_fp(ds,sampleno,1,buffer,dither_mode,NULL)!=1);
663
669
static gboolean datasource_uses_file(Datasource *ds, gchar *filename)
689
695
ds = (Datasource *)l->data;
690
696
if (!datasource_uses_file(ds,filename)) continue;
692
/* FIXME: When multiple tempdir support has been added, try moving to
693
* all different partitions before copying */
698
/* For the first affected datasource (backup == NULL), the file is
699
* moved to a temporary directory and the filename in the datasource
700
* is updated. For each remaining sources, the file is copied.
702
* This is not optimal, but the case with more than one reference to
703
* a file can only happen when the user has opened the same file
694
706
if (backup == NULL) {
707
/* This loop first tries to move the file to each temporary
708
* directory. If all directories fail, we copy the file. */
697
711
t = get_temp_filename(dirnum);
760
774
ds = gtk_type_new(datasource_get_type());
761
775
ds->type = DATASOURCE_CONVERT;
762
776
memcpy(&(ds->format),new_format,sizeof(Dataformat));
777
ds->format.samplebytes = ds->format.samplesize * ds->format.channels;
763
778
ds->length = source->length;
764
779
ds->bytes = ds->length * new_format->samplebytes;
765
780
ds->data.clone = source;
767
782
gtk_object_sink(GTK_OBJECT(source));
787
static gint datasource_clip_check_fp(Datasource *ds, StatusBar *bar)
793
g_assert(ds->format.type == DATAFORMAT_FLOAT);
794
if (datasource_open(ds)) return -1;
795
buf = g_malloc(sizeof(sample_t) * ds->format.samplebytes);
796
for (o=0; o<ds->length; ) {
797
i = datasource_read_array_fp(ds,o,NS,buf,DITHER_UNSPEC,&clipcount);
801
datasource_close(ds);
806
datasource_close(ds);
809
if (status_bar_progress(bar,NS)) {
811
datasource_close(ds);
815
datasource_close(ds);
821
gint datasource_clip_check(Datasource *ds, StatusBar *bar)
825
case DATASOURCE_SNDFILE:
826
case DATASOURCE_SNDFILE_TEMPORARY:
827
/* Libsndfile is always used with normalization turned on */
829
case DATASOURCE_SILENCE:
832
case DATASOURCE_REAL:
833
case DATASOURCE_VIRTUAL:
834
case DATASOURCE_TEMPFILE:
835
/* If we contain PCM data, clipping can't occur */
836
if (ds->format.type == DATAFORMAT_PCM) return 0;
837
return datasource_clip_check_fp(ds,bar);
838
case DATASOURCE_BYTESWAP:
839
case DATASOURCE_CLONE:
840
/* This could cause clipping in special cases.
841
* That clipping can not be solved by normalizing the data. */
842
i = datasource_clip_check(ds->data.clone,bar);
845
if (ds->format.type == DATAFORMAT_FLOAT)
846
return datasource_clip_check_fp(ds,bar);
850
case DATASOURCE_CONVERT:
851
return datasource_clip_check(ds->data.clone,bar);
855
g_assert_not_reached();