前提・実現したいこと
C言語初心者です。このサイトにて初めて質問させていただきます。
C言語でMIDIファイルの中身の16進数の一部を削除する編集プログラムを作っています。
こちらのサイト(http://torasukenote.blog120.fc2.com/blog-entry-104.html)の
「4.トラックチャンクも読み込もう!」のプログラムに16進数の一部を削除するプログラムを追加したいのですが、上手くいかず困っています。
とりあえず16進数1つでもいいので削除ができればと思っております。
拙い文章ではありますが、ご回答お待ちしております。
該当のソースコード
ソースコード #include <stdio.h> #include <stdlib.h> typedef struct { // トラックチャンクのデータを格納する構造体 char type[4]; // チャンクタイプを示す文字列を格納。「MTrk」が入るはず。[4byte] int size; // トラックチャンクデータのサイズ [4byte] char *data; // トラックデータ(MIDIイベントの羅列)へのポインタ } TrackChunk; int convertEndian(void *input, size_t s){ // エンディアン変換をおこなう関数 // stdlib.hをインクルードしてください。 // 【引数】: void *input...エンディアン変換対象へのポインタ // 【引数】: size_t s...変換対象のバイト数 int i; // カウンタ char *temp; // 変換時に用いる一時的配列 if((temp = (char *)calloc(s, sizeof(char))) == NULL){ perror("Error: Cannot get memory for temp."); return 0; // 領域確保できず(失敗) } for(i=0; i<s; i++){ // inputデータをtempに一時保管 temp[i] = ((char *)input)[i]; } for(i=1; i<=s; i++){ // tempデータを逆方向にしてinputへ代入 ((char *)input)[i-1] = temp[s-i]; } free(temp); // 確保した領域を解放 return 1; // 正常終了 } int main(){ int i, j; // カウンタ FILE *fp; // ファイルポインタ生成 int endian; // エンディアン判定にいろいろ使用(0:BigEndian, 1:LittleEndian) // ヘッダチャンク情報 char header_chunk_type[4]; // チャンクタイプを示す文字列を格納。「MThd」が入るはず。[4byte] int header_chunk_size; // ヘッダチャンクデータのサイズ [4byte] short smf_format; // SMFのフォーマットタイプ(0か1か2) [2byte] short tracks; // トラックチャンク総数 [2byte] short division; // 四分音符あたりの分解能(ここではデルタタイム) [2byte] // トラックチャンク情報 TrackChunk *track_chunks; // トラックチャンク情報を格納する配列のためのポインタ // エンディアン判定 endian = 1; if(*(char *)&endian){ // リトルエンディアンなら... endian = 1; // Little Endian } else { // ビッグエンディアンなら... endian = 0; // Big Endian } // MIDIファイルを開く if((fp = fopen("./midi/theme01.mid", "rb")) == NULL){ // バイナリ読み取りモードでファイルを開く perror("Error: Cannot open the file."); // 失敗したらエラーを吐く return 0; } // ヘッダチャンク取得 fread(header_chunk_type, 1, 4, fp); // チャンクタイプ fread(&header_chunk_size, 4, 1, fp); // チャンクデータサイズ fread(&smf_format, 2, 1, fp); // SMFフォーマットタイプ fread(&tracks, 2, 1, fp); // トラックチャンク総数 fread(&division, 2, 1, fp); // 分解能(デルタタイム) // 必要ならエンディアン変換 if(endian){ // リトルエンディアンなら要変換 // エンディアン変換処理 convertEndian(&header_chunk_size, sizeof(header_chunk_size)); convertEndian(&smf_format, sizeof(smf_format)); convertEndian(&tracks, sizeof(tracks)); convertEndian(&division, sizeof(division)); } // 読み取ったヘッダチャンク情報を出力 printf("# Header ========================\n"); printf("header_chunk_type : %c%c%c%c\n", header_chunk_type[0], header_chunk_type[1], header_chunk_type[2], header_chunk_type[3]); printf("header_chunk_size : %d\n", header_chunk_size); printf("smf_format : %hd\n", smf_format); printf("tracks : %hd\n", tracks); printf("division : %hd\n", division); // トラックチャンク取得 if((track_chunks = (TrackChunk *)calloc(tracks, sizeof(TrackChunk))) == NULL){ // トラック数に応じて領域確保 perror("Error: Cannot get memory for track_chunks."); return 0; // 領域確保できず(失敗) } for(i=0; i<tracks; i++){ // トラック数だけ繰返し fread(track_chunks[i].type, 1, 4, fp); // チャンクタイプ fread(&track_chunks[i].size, 4, 1, fp); // チャンクデータサイズ if(endian){ // リトルエンディアンなら要変換 convertEndian(&track_chunks[i].size, sizeof(track_chunks[i].size)); } if((track_chunks[i].data = (char *)calloc(track_chunks[i].size, sizeof(char))) == NULL){ // データサイズに応じて領域確保 perror("Error: Cannot get memory for track_chunks[i].data ."); return 0; // 領域確保できず(失敗) } fread(track_chunks[i].data, track_chunks[i].size, sizeof(char), fp); // データ(MIDIイベントの羅列) //fread関数は第一引数には格納先のバッファ、第二引数は読み込むデータ1つのバイト数、 //第三引数は読み込むデータの個数、第四引数はファイルポインタを指定します。 } // 読み取ったトラックチャンク情報を出力, for(i=0; i<tracks; i++){ // トラック数だけ繰返し printf("# Track[%02d] =====================\n", i); printf("track_chunks[%d].type : %c%c%c%c\n", i, track_chunks[i].type[0], track_chunks[i].type[1], track_chunks[i].type[2], track_chunks[i].type[3]); printf("track_chunks[%d].size : %d\n", i, track_chunks[i].size); printf("track_chunks[%d].data: \n", i); for(j=0; j<track_chunks[i].size; j++){ printf("%02x ", (unsigned char)track_chunks[i].data[j]); // 16進表記で出力 02は上位で足りない桁を文字0で埋め、最小2桁で表示する xは整数を16進で出力する if(!((j+1)%40)) printf("\n"); // 40バイト出力するたびに改行 //else if(!((j+1)%10)) printf(": "); // 10バイト出力するたびに区切る } printf(" \n"); } return 1; }
試したこと
補足情報(FW/ツールのバージョンなど)
OS:Windows10 使用環境:Atom