Project Structure - richardjwild/arctracker GitHub Wiki

I had now reached the point where there was no code left in the project that I felt awful about and had to clean up. The main loop inside play_mod.c was a bit too large for my liking, but I decided to leave it alone for the moment, because I was planning later to add support for PortAudio so that I could move development from the virtual machine to my Macbook. Implementing support for PortAudio would require moving from a blocking audio i/o model, as Arctracker currently uses, to a callback-based model, which would involve pulling the playroutine more or less inside-out. Therefore I didn't see any point refactoring it further, given that it was probably going to undergo radical change anyway. It was clean enough to be getting on with.

For now, I really wanted to change the project structure. All the project files were stored in a single directory, which was bad when Arctracker comprised just four C files, but was seriously untidy now that it comprised a half dozen or so. Also the Makefile had been allowed to get out of date, it did not include all of the header file dependencies. So the first thing I did was refactor the Makefile which also involved improving my skills with make.

Next I moved all the source files into a new src directory, which also involved removing quite a lot of my previous changes to the Makefile. I also arranged for all the object files to be compiled into an objs directory, and the executable to be placed in bin. Now this all was an improvement, but I wanted to go further. The source files were now all kept separate, but I really wanted to split them up into subdirectories to organise them better. Unfortunately I also had to remove the header file dependencies, which was a serious issue that needed to be fixed, because now the build system would not rebuild the project if one of the header files changed.

In the next commit I separated the source code into subdirectories:

src
 |-- arctracker.c
 |-- arctracker.h
 |-- config.h
 |-- Makefile
 |-- audio
 |    |-- audio_api.h
 |    |-- gain.c
 |    |-- gain.h
 |    |-- mix.c
 |    |-- mix.h
 |    |-- mu_law.h
 |    |-- period.c
 |    |-- period.h
 |    |-- resample.c
 |    |-- resample.h
 |    |-- write_audio.c
 |    +-- write_audio.h
 |-- audio_api
 |    |-- alsa.c
 |    |-- alsa.h
 |    |-- oss.c
 |    +-- oss.h
 |-- chrono
 |    |-- clock.c
 |    +-- clock.h
 |-- formats
 |    |-- desktop_tracker_module.c
 |    |-- desktop_tracker_module.h
 |    |-- tracker_module.c
 |    +-- tracker_module.h
 |-- io
 |    |-- configuration.c
 |    |-- configuration.h
 |    |-- console.c
 |    |-- console.h
 |    |-- error.c
 |    |-- error.h
 |    |-- read_mod.c
 |    +-- read_mod.h
 |-- memory
 |    |-- bits.h
 |    |-- heap.c
 |    +-- heap.h
 +-- playroutine
      |-- effects.c
      |-- effects.h
      |-- play_mod.c
      |-- play_mod.h
      |-- sequence.c
      +-- sequence.h

I struggled mightily with the Makefile trying to write a general rule for compiling object files, that would compile src/audio/gain.c and write objs/gain.o. It always wanted to create objs/audio/gain.o instead. While fiddling, I accidentally discovered that compiling and linking all the source files into the executable in one command was considerably faster than compiling all the object files and linking them separately. I pondered this for a while, and decided I could not think of any advantages to compiling and linking separately in a project this size, so I abandoned the struggle and just went with it. I re-added the header files as dependencies, which was now trivially easy because the single build step now depended on everything.

Previous: Effects | Next: Floating Point Samples