/* * compile with: * * gcc -o seek -Wall -lsndfile seek.c */ #include #include #include #include #include #include int main (int argc, char **argv) { SF_INFO info; int mode; sf_count_t file_frames; SNDFILE *file; char *filename = "/tmp/sndtest.aiff"; /* create soundfile */ mode = SFM_WRITE; info.samplerate = 48000; info.channels = 2; /* behavior seems to be bound to a specific file format */ info.format = SF_FORMAT_AIFF | SF_FORMAT_PCM_16; /* delete if already there */ { struct stat st; if (! stat(filename, &st)) { remove(filename); } } /* open */ if ((file = sf_open(filename, mode, &info)) == NULL) { fprintf(stderr, "libsndfile(open): %s\n", sf_strerror(file)); exit(EXIT_FAILURE); } /* close without writing: just write header */ if (sf_close(file)) { fprintf(stderr, "libsndfile(close): %s\n", sf_strerror(file)); exit(EXIT_FAILURE); } /* open again for writing */ mode = SFM_RDWR; /* !!! */ info.format = 0; if ((file = sf_open(filename, mode, &info)) == NULL) { fprintf(stderr, "libsndfile(open): %s\n", sf_strerror(file)); exit(EXIT_FAILURE); } /* remember number of frames in file */ file_frames = info.frames; /* in auto header update mode, seeking to the end of the file with SEEK_SET will fail from the 2nd seek on. seeking to 0, SEEK_END will seek to 0 anyway */ if (! sf_command(file, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE)) { fprintf(stderr, "libsndfile(sf_command): %s\n", sf_strerror(file)); exit(EXIT_FAILURE); } /* now write some frames */ { float buffer[1024]; int blocks = 4; /* we want to write blocks times the buffer */ long err; int frames = 1024 / info.channels; int i; for (i = 0; i < blocks; ++i) { fprintf(stderr, "trying to seek to position %d, file_frames: %ld\n", i * frames, (long)file_frames); /* this will fail from the 2nd seek on */ if ((err = sf_seek(file, i * frames, SEEK_SET)) == -1) /* this will seek to 0 regardless of the number of frames in the file */ /* if ((err = sf_seek(file, 0, SEEK_END)) == -1) */ { fprintf(stderr, "libsndfile(sf_seek): %s\n", sf_strerror(file)); } else { fprintf(stderr, "seeked to position %ld\n", err); } /* write */ if ((err = sf_writef_float(file, buffer, frames)) == -1) { fprintf(stderr, "libsndfile: sf_writef_float(): %s\n", sf_strerror(file)); } else { fprintf(stderr, "wrote %ld frames\n", err); file_frames += err; } } } /* close */ if (sf_close(file)) { fprintf(stderr, "libsndfile(close): %s\n", sf_strerror(file)); exit(EXIT_FAILURE); } return EXIT_SUCCESS; } /* main */