summaryrefslogblamecommitdiffstatshomepage
path: root/src/lib/formats/cassimg.h
blob: 5199c0e4a0436f27e6f16174e1fbc1a5ce25395d (plain) (tree)
1
2
3
4
5
6
7
8
9

                                 






                                                                      

                              
 


                    
 
                    
                     


                 
 
                   
                                 
      
 




                                             





                                                                            



                                         
 






                                         
 

                                         


                



                                                                    
     



                                                                    








                                                                            
                                          




                            
                                  





                            
                                  


                            
                     
 

                        





                                                                                           

          

                                            


                     
                                  
 
                                           
                            

  


                               


                                                                                                  






                                       
                                        

                                   
                                       





                                                       
                                                    

                          

                                                                   







                                                  
                                             

                                                        


                                                     
                                
                                             
                        
                                             
                                                        









                                                                            
                                                                             
                                                                                      
                                                                                                                   
                                                                                              
                                                                                                                    
                                                                                     
                                                              




                                                                                                                                         


                                                                                                        

                       
                                                                                 
                                                                                            
                                           
                                                                                 
                                                                                            
                                                 
                                                                                
                                                                  
                                                                                
                                                                 
 
                                                                                              
                                                                                                      
                                                                                        
                                                                                                       
                                                                                        

                        
                                                                                                                         
                                      
                                                                                                           

                                                                                          
                                                                                                             
                                                                                          
                                   
                                                                                                            
                                                                                      
                                   
                                                                                                               
                                                                  





                                                                

                                      
                                                                                                      
                                                            
                                                                         

                                                            
                                
// license:BSD-3-Clause
// copyright-holders:Nathan Woods
/*********************************************************************

    cassimg.h

    Cassette tape image abstraction code

*********************************************************************/
#ifndef MAME_FORMATS_CASSIMG_H
#define MAME_FORMATS_CASSIMG_H

#pragma once

#include "ioprocs.h"

#include "osdcore.h"
#include "coretmpl.h"

#include <string>
#include <vector>

#ifndef LOG_FORMATS
#define LOG_FORMATS if (0) printf
#endif

// hack to get around rogues that define this
#ifdef UNSUPPORTED
#undef UNSUPPORTED
#endif

/***************************************************************************

    Constants

***************************************************************************/

#define CASSETTE_FLAG_READWRITE         0
#define CASSETTE_FLAG_READONLY          1
#define CASSETTE_FLAG_NOSAVEONEXIT      0
#define CASSETTE_FLAG_SAVEONEXIT        2

#define CASSETTE_WAVEFORM_8BIT          0
#define CASSETTE_WAVEFORM_16BIT         2
#define CASSETTE_WAVEFORM_16BIT_FLIP    3
#define CASSETTE_WAVEFORM_32BIT         4
#define CASSETTE_WAVEFORM_32BIT_FLIP    5
#define CASSETTE_WAVEFORM_ENDIAN_FLIP   1
#define CASSETTE_WAVEFORM_UNSIGNED      8

#define CASSETTE_MODULATION_SQUAREWAVE  0
#define CASSETTE_MODULATION_SINEWAVE    1


#ifdef LSB_FIRST
#define CASSETTE_WAVEFORM_16BITBE       CASSETTE_WAVEFORM_16BIT_FLIP
#define CASSETTE_WAVEFORM_16BITLE       CASSETTE_WAVEFORM_16BIT
#define CASSETTE_WAVEFORM_32BITBE       CASSETTE_WAVEFORM_32BIT_FLIP
#define CASSETTE_WAVEFORM_32BITLE       CASSETTE_WAVEFORM_32BIT
#else
#define CASSETTE_WAVEFORM_16BITBE       CASSETTE_WAVEFORM_16BIT
#define CASSETTE_WAVEFORM_16BITLE       CASSETTE_WAVEFORM_16BIT_FLIP
#define CASSETTE_WAVEFORM_32BITBE       CASSETTE_WAVEFORM_32BIT
#define CASSETTE_WAVEFORM_32BITLE       CASSETTE_WAVEFORM_32BIT_FLIP
#endif


/***************************************************************************

    Type definitions

***************************************************************************/

typedef std::vector<int32_t> sample_block;

struct CassetteOptions
{
	int channels;
	int bits_per_sample;
	uint32_t sample_frequency;
};

struct CassetteInfo
{
	int channels;
	int bits_per_sample;
	uint32_t sample_frequency;
	size_t sample_count;
};

struct cassette_image
{
	enum class error
	{
		SUCCESS,                // no error
		INTERNAL,               // fatal internal error
		UNSUPPORTED,            // this operation is unsupported
		OUT_OF_MEMORY,          // ran out of memory
		INVALID_IMAGE,          // invalid image
		READ_WRITE_UNSUPPORTED  // read/write is not supported by this image format
	};

	const struct CassetteFormat *format;
	struct io_generic io;

	int channels;
	int flags;
	uint32_t sample_frequency;

	std::vector<sample_block *> blocks;
	size_t sample_count;
};

struct CassetteFormat
{
	const char *extensions;
	cassette_image::error (*identify)(cassette_image *cassette, struct CassetteOptions *opts);
	cassette_image::error (*load)(cassette_image *cassette);
	cassette_image::error (*save)(cassette_image *cassette, const struct CassetteInfo *info);
};

/* used for the core modulation code */
struct CassetteModulation
{
	int flags;
	double zero_frequency_low;
	double zero_frequency_canonical;
	double zero_frequency_high;
	double one_frequency_low;
	double one_frequency_canonical;
	double one_frequency_high;
};

/* code to adapt existing legacy fill_wave functions */
struct CassetteLegacyWaveFiller
{
	int (*fill_wave)(int16_t *, int, uint8_t *);
	int chunk_size;
	int chunk_samples;
	int (*chunk_sample_calc)(const uint8_t *bytes, int length);
	uint32_t sample_frequency;
	int header_samples;
	int trailer_samples;
};

/* builtin formats */
extern const struct CassetteFormat wavfile_format;

/* macros for specifying format lists */
#define CASSETTE_FORMATLIST_EXTERN(name)    \
	extern const struct CassetteFormat *const name[]

#define CASSETTE_FORMATLIST_START(name)     \
	const struct CassetteFormat *const name[] = \
	{                                       \
		&wavfile_format,
#define CASSETTE_FORMAT(name)               \
		&(name),
#define CASSETTE_FORMATLIST_END             \
		nullptr                                \
	};

CASSETTE_FORMATLIST_EXTERN(cassette_default_formats);

/***************************************************************************

    Prototypes

***************************************************************************/

cassette_image::error cassette_open(void *file, const struct io_procs *procs,
	const struct CassetteFormat *format, int flags, cassette_image **outcassette);
cassette_image::error cassette_open_choices(void *file, const struct io_procs *procs, const std::string &extension,
	const struct CassetteFormat *const *formats, int flags, cassette_image **outcassette);
cassette_image::error cassette_create(void *file, const struct io_procs *procs, const struct CassetteFormat *format,
	const struct CassetteOptions *opts, int flags, cassette_image **outcassette);
cassette_image::error cassette_save(cassette_image *cassette);
void cassette_close(cassette_image *cassette);
void cassette_change(cassette_image *cassette, void *file, const struct io_procs *procs, const struct CassetteFormat *format, int flags);
void cassette_get_info(cassette_image *cassette, struct CassetteInfo *info);

/* calls for accessing the raw cassette image */
void cassette_image_read(cassette_image *cassette, void *buffer, uint64_t offset, size_t length);
void cassette_image_write(cassette_image *cassette, const void *buffer, uint64_t offset, size_t length);
uint64_t cassette_image_size(cassette_image *cassette);

/* waveform accesses */
cassette_image::error cassette_get_samples(cassette_image *cassette, int channel,
	double time_index, double sample_period, size_t sample_count, size_t sample_spacing,
	void *samples, int waveform_flags);
cassette_image::error cassette_put_samples(cassette_image *cassette, int channel,
	double time_index, double sample_period, size_t sample_count, size_t sample_spacing,
	const void *samples, int waveform_flags);
cassette_image::error cassette_get_sample(cassette_image *cassette, int channel,
	double time_index, double sample_period, int32_t *sample);
cassette_image::error cassette_put_sample(cassette_image *cassette, int channel,
	double time_index, double sample_period, int32_t sample);

/* waveform accesses to/from the raw image - these are only used by lib\formats\wavfile.cpp */
cassette_image::error cassette_read_samples(cassette_image *cassette, int channels, double time_index,
	double sample_period, size_t sample_count, uint64_t offset, int waveform_flags);
cassette_image::error cassette_write_samples(cassette_image *cassette, int channels, double time_index,
	double sample_period, size_t sample_count, uint64_t offset, int waveform_flags);

/* modulation support */
cassette_image::error cassette_modulation_identify(cassette_image *cassette, const struct CassetteModulation *modulation,
	struct CassetteOptions *opts);
cassette_image::error cassette_put_modulated_data(cassette_image *cassette, int channel, double time_index,
	const void *data, size_t data_length, const struct CassetteModulation *modulation,
	double *time_displacement);
cassette_image::error cassette_put_modulated_filler(cassette_image *cassette, int channel, double time_index,
	uint8_t filler, size_t filler_length, const struct CassetteModulation *modulation,
	double *time_displacement);
cassette_image::error cassette_read_modulated_data(cassette_image *cassette, int channel, double time_index,
	uint64_t offset, uint64_t length, const struct CassetteModulation *modulation,
	double *time_displacement);
cassette_image::error cassette_put_modulated_data_bit(cassette_image *cassette, int channel, double time_index,
	uint8_t data, const struct CassetteModulation *modulation,
	double *time_displacement);

/* debug calls */
void cassette_dump(cassette_image *image, const char *filename);

/* legacy code support */
#define CODE_HEADER     ((uint8_t*)-1)
#define CODE_TRAILER    ((uint8_t*)-2)
cassette_image::error cassette_legacy_identify(cassette_image *cassette, struct CassetteOptions *opts,
	const struct CassetteLegacyWaveFiller *legacy_args);
cassette_image::error cassette_legacy_construct(cassette_image *cassette,
	const struct CassetteLegacyWaveFiller *legacy_args);

#endif // MAME_FORMATS_CASSIMG_H