教えてください

[戻る]
スヌーピー 2002/07/18(木) 11:47:15
はじめまして!
今VisualC++ Ver6.0を使ってプログラムを作っていますが、わからないことがあり行き
詰っています。教えてください。
今、あるテキストファイルから音声ファイルを作成するプログラムを作っています。
どのような手順でプログラムを進行していけばよろしいでしょうか??
音声を作成するにはどのような構文で書いたらいいのか教えて!!

wood 2002/07/18(木) 12:15:19
どこかの音声再生エンジンを利用させてもらうのが早くありませんか

質問の内容からすると全くプログラミングどころか、仕様すら決まっていない感じですけど

[E-Mail] 2002/07/18(木) 13:05:38
回答ではありません。
質問内容の具体化を進めるという意味で。

> 今、あるテキストファイルから音声ファイルを作成するプログラムを作っています。
テキストファイルには何が記述されていますか?
作成しようとしている音声ファイルはどのような形式を考えていますか?

あと、タイトルが「教えてください」だと回答数は激減すると思われます。

Joan 2002/07/18(木) 15:14:45
>今、あるテキストファイルから音声ファイルを作成するプログラムを作っています。

僕のコンピュータに Windows 2000 + Office XP がインストールされています。
コントロールパネルの中に「スピーチ」という音声合成のプロパティがあるのですが
ocxっぽいので調べてみてらどうでしょうか?棒読みですが、意外と聞こえるます。
プレビューできるのでやってみてください。なんか SAPI というのがあるみたいですが。
http://www.google.co.jp/search?sourceid=navclient&hl=ja&q=SAPI

正直、自前で音声合成は無理っぽい感じがしますが。音声認識でもあの音とおの音が明確に
分かってないので、声のサンプルの方にも限界があるかと。サンプルがあっても、
アクセントやイントネーションも難しいですしね・・・。
それとも音声とは楽器の方でしょうか?こっちは MIDI で実現しているので現実的です。

>どのような手順でプログラムを進行していけばよろしいでしょうか??
>音声を作成するにはどのような構文で書いたらいいのか教えて!!

音声出力(音声合成)は、まだまだ研究段階の域ですので音声出力のやり方を教えられる
人なんて専門の教授・研究者じゃないと無理かと・・・。
パッケージソフトでエンジンを別に購入するがベストかと。

a 2002/07/18(木) 23:26:08
音声合成にもいくつかありまして、
1.自前で音を作成する
  これは実際にフォルマンとだとか、基本周波数等を考え、 
  音を作成します。

2.DBなどを参照する。
  「あ」を発音したいなら、あらかじめ用意されてるDBから
  「あ」の音声を引っ張ってくる。

1.はしんどいですが、2は簡単ですよ。

wood 2002/07/19(金) 03:38:01
aさんの2番の場合について
この方法は20年以上前にやったことありますよ(当時 高校1年)
当時の新聞あればそこにソースコード乗ってますけど
かなり変人扱いされましたけど...
アセンブラで(CPU:80286)

そこで技術的助言でしかないのですが
1.正弦波などの関連語句を勉強しましょう
2.オシロスコープを利用しましょう(水平・垂直 両用のもの)
3.音源ボード 制御についてはアセンブラレベルで利用可能になれば
  かなり精度のいい音声エンジン作成できるよ
4.録音する声は、男性の声で行いましょう
  2.で確認すると意味わかりますよ
5.昔のはなしですけどデジタル化するとアナログデータの50%を消失します
  実際に聞こえるには支障ありませんけど

6.声色の変更は、音声送出速度の変更で可能になります
7.イントネーションについては「基本文体」を用意することで可能になるはずです
8.基本録音データとしてアナログ音1文字につき2KBもあれば十分のはず
今思い出せるのはここまでくらいです


でも今なら、音声エンジン結構いろんなところから出ているから
最初に書いたように、それを利用するほうがかなり楽だと思います

スヌーピー 2002/07/22(月) 13:20:21
テキストファイルにある情報は生の情報です。生っていっても一応数値のみのテキスト
で考えています。その情報をWAVEに変換するプログラムを考えています。

a 2002/07/22(月) 17:06:25
>テキストファイルにある情報は生の情報です。生っていっても一応数値のみのテキスト
>で考えています。その情報をWAVEに変換するプログラムを考えています。
その数値が何を表しているかわからないのですが、
音声をサンプリングした値でしょうか?
それならwaveファイルの構造をしらべてみましょう。
そうすればwaveファイルに変換できるはずです。

wood 2002/07/22(月) 18:27:13
音声(人の声)と音階(ピアノ演奏など)どちらの表現を必要としているのでしょうか?
単純な方法とすればマイク録音により必要な分だけのwaveを作成して
対応するものを作成してはどうですか

Joan 2002/07/22(月) 23:51:29
> テキストファイルにある情報は生の情報です。
> 生っていっても一応数値のみのテキストで考えています。
ふー、やっと理解できました。
テキストファイルというと、文章ファイルの事を示すので数値データなら
テキスト化された数値データとか書いてくれるとわかりやすいです。

> その情報をWAVEに変換するプログラムを考えています。

「WAVEFORMATEX 構造体」で検索をすれば高確率で WAVE ファイル
フォーマット情報を調べれると思います。

手順は
1.テキストファイルから数値データを読み出す
2.WAVE ファイルに書き出す

です。???というか、WAVEファイルヘッダーを先頭に付けて
数値データをバイナリに変換すればいいだけじゃないかと
思うのですが??


ただ、「数値データ」といわれても、モノラルかステレオの
どっちで保存されたものでしょうか?また、数値化されたデータ
の精度はどんなものでしょうか?
とか、いろいろ謎めいてきます。

まぁ WAVEファイルを勉強してくれればその辺は理解できるかと
思います。

スヌーピー 2002/07/23(火) 10:49:03
テキストファイルには数値情報が入っています。例えば25555464という情報が入ってい
るものとして考えています。このような情報が沢山入っている一つのデータだとして考
えています。その情報にはモノラル、ステレオ、8ビット、16ビット、サンプリング
レート等の情報はないものです。それを、WAVEに変換使用と考えています。数値だけの
情報です。ファイルサイズとかはどのようにしたらわかるのでしょうか。プロパティと
かでファイルサイズを見た所5Mとしたら、それがそのままWAVEのファイルサイズになる
のでしょうか??

a 2002/07/23(火) 11:56:19
>テキストファイルには数値情報が入っています。例えば25555464という情報が入ってい
>るものとして考えています。このような情報が沢山入っている一つのデータだとして考
>えています。その情報にはモノラル、ステレオ、8ビット、16ビット、サンプリング
>レート等の情報はないものです。それを、WAVEに変換使用と考えています。数値だけの
>情報です。ファイルサイズとかはどのようにしたらわかるのでしょうか。プロパティと
>かでファイルサイズを見た所5Mとしたら、それがそのままWAVEのファイルサイズになる
>のでしょうか??

1.ファイルサイズ取得
CFile::GetLengthとか。。。

2. >それがそのままWAVEのファイルサイズになるのでしょうか??

まずはwaveファイルの構造を調べてください

wood 2002/07/23(火) 12:21:32
質問
WAVE系を処理している サンプルプログラムは見たことありますか?
MSDNに結構載ってますけど参考にしたことありますか

kazuma 2002/07/23(火) 13:09:53
google で「WAV ファイルフォーマット」などで検索すると、
解説しているページが結構見つかりますよ。

あと、↓のページは各種ファイルフォーマットに関する情報が豊富です。
http://www.wotsit.org/

さらに、こんなものがあるようです。
http://www.vector.co.jp/soft/win95/art/se057421.html

Joan 2002/07/23(火) 18:03:45
>その情報にはモノラル、ステレオ、8ビット、16ビット、
> サンプリングレート等の情報はないものです。
そのファイルにそれらの情報が含まれている必要はないですが、WAVEファイル
を書き出す時に サンプリング周波数、量子化ビット数、チャンネル数が
最低決まっていないとファイルを再生することができません。
少なくてもこの3つは先に与えられていないと、変換できません。

>テキストファイルには数値情報が入っています。
>例えば25555464という情報が入っているものとして考えています。
>このような情報が沢山入っている一つのデータだとして考えています。
うーん、25555464 っていう値をとっちゃいますか?だとするとかなり困難です。
普通は量子化数は符号整数16bit 要するに signed short が1つのサンプルに
なります。値が取れる範囲は、だいたい±32,000の範囲になります。
なので、この範囲に収めなくてはいけません。一番大きい値をとるサンプルを
探して 16bit に収まるような倍率を求めて、その倍率で全部のサンプルを
小さくしなくてはいけませんし・・・。

> プロパティとかでファイルサイズを見た所5Mとしたら、それがそのままWAVEの
> ファイルサイズになるのでしょうか??
テキストとバイナリって知ってますか?それぞれの特徴を知っていればこんな
ことは聞かないかと思いますが・・・。

スヌーピー 2002/07/25(木) 10:25:31
もう少し詳しくデータについて書き込みます。
0x25555464というデータを一つの値として読み込みを行うにはどのようにしたらいいの
でしょうか??
RAWという拡張子やDATという拡張子の中に沢山のデータが入っているものとして考えて
います。
皆さんに細かく教えていただき幸いに思っています。まだ、完成には程遠いのですがよ
ろしくお願いします

wood 2002/07/25(木) 12:26:17
入力元データのフォーマットどうなっているんですか
RAWとDATではフォーマット(データの並び)違うと思いますけど
拡張子に関係なく変換したいのでは無いのですか
またそれがどういう意味を持っているのか分かりませんけど?
また、最初は十進だったけど、今度は16進ですか
取り合えづバイナリなりテキストなりで読み込んで
バイトを区切って変換すればよいのではないですか

仕様の確立してから分からない部分を明確にして再質問してはどうですか
皆さんおおざっぱ過ぎてどう解答して良いかわかんないと思います

Joan 2002/07/25(木) 14:16:59
char* をint へ変換する関数がCランタイムの中にあります。
atof、atoi、_atoi64、atol
これらを使えば、十分読み込めます。
どうしても、わからなければ入門書を参考にしてください。

スヌーピー 2002/07/25(木) 17:55:35
その一つのデータ0x25555464を0x2555というデータと0x5464というデータに分けるには
どのようにしたらいいのでしょうか??

WAVEの構造体は理解していますが、うまくプログラムを作成できなくて悩んでいます。
参考程度に教えてください

wood 2002/07/25(木) 21:03:16
単純にcharで読むのはだめなんですか
共用体使ってみてはどうですか

a 2002/07/25(木) 21:23:01
もう少し基本を勉強してみてはどうでしょう?
後々必ず役立つと思いますが。。。

Joan 2002/07/26(金) 14:31:11
>WAVEの構造体は理解していますが、うまくプログラムを作成できなくて悩んでいます。
そうですね。
まず、WAVEファイルを書き出すクラスを作ってみましょう。そっちの方が
後で使うときは便利です。私はWin32API好きなのでランタイム関数は
あまり使いませんので、fopen や stream なり、好きに書き直してください。

メンバ関数に[データ部]の読み書きができる関数を作ると便利です。

メンバ関数は
public:
 CreateFile(DWORD samplePerSec, DWORD channel, DWORD bitPerSample);
 Close();

 Read(char* pBuf, size_t ReadSize);    // データ部をよみこみます
 Write(char* pBug, size_t WriteSize);  // データ部へ書き出します
メンバ変数は
 WAVEFORMATEX* mlpWfx;   // 可変サイズの構造体なのでかならずヒープで確保する
 DWORD m_SizeOfFile;  // ファイルのサイズ
 DWORD m_SizeOfData;  //  データのサイズ
protected:       // 内部関数
  HANDLE hFile; // ファイルハンドル
  
  // API ラッパー
  CreateFile_API();
  Read_API();
  Write_API(char* pBug, size_t WriteSize);
 
(戻り値を省いたので適当に返してください)

フォーマットは以下のようになってますから

'RIFF'
ファイルサイズ
'WAVE'
'fmt '
WAVEFORMATEX構造体のサイズ
'data'
リアルデータ部のサイズ


サイズは DWORD か unsigned int で
''の4文字は char[4] かな。

ヘッダーはファイルサイズやデータ部のサイズがあるので
ヘッダーのサイズだけダミーデータを書き込むようにして
Close 関数が呼ばれたときに全体のサイズを集計して
ヘッダーを書き直してせばよいかと。

本来 mmio を使うようなのですが mmio の方が楽なのでしょうか。
分かりませんが。私は自前でがんばりましたが・・・。

DirectShowのWAVE File Writer を使う手もありますし、
検索すれば WaveFile の入出力関数、クラスのサンプル
ぐらい出てきそうですが・・・。

スヌーピー 2002/07/30(火) 13:27:27
よろしければ、細かくサンプルプログラムを頂けたら幸いです。

まだ完成にはいたって降りません。

まだ沢山聞くことがあると思いますがよろしくお願いします

スヌーピー 2002/07/31(水) 18:20:40
RAWというファイルの中身が
0x5265ABFF  0x12348789  0x54878888 ・・・・・・・・・・・・・・・
になっています。
これを一つのデータを読込むにはどのようにしたらいいのでしょうか??

あと、例えばこの数値(0x5265ABFF)を 0x5265 と 0xABFFに分けるにはどのようにし
たらいいのでしょうか??

参考程度にプログラム例も教えていただけたら嬉しいです。

Joan 2002/07/31(水) 21:11:54
うーん、簡単な文字列操作だと思いますが。
0x5265ABFFの文字列を配列の箱にれると下のように
なります。

-----------------------------------------
| 0 | x | 5 | 2 | 6 | 5 | A | B | F | F |
----------------------------------------- 

10文字なので10個の char 配列を用意します。
先頭の 6 文字だけコピー他の char 配列にコピー
すれば 0x5265 を取れます。そして残りの ABFF
も取り除いて 0x を先頭に付けないといけないので
strcat 関数を使ってくっつけます。

MFCを使っているならCString を char の代わりに
使用して Mid メンバ関数を使うと簡単です。

例もなにも・・・。書いてみたら3行でしたよ。
CString data = "0x5265ABFF";
CString result1 = data.Mid(0,6);
CString result2 = "0x" + data.Mid(6);

ファイルの入出力のところはじぶんでやってみてくだ
さい。では。

スヌーピー 2002/08/02(金) 14:31:13
ファイルの入出力がうまくいきません。よろしければ教えていただけませんか??

とおりすがり 2002/08/02(金) 15:00:21
ほんとに自分でやってるのですか?
発言開始から全くソースが出てきてませんが。。。
うまくいかないなら、何がうまくいかないのかを質問する方がいいと思います。
そして、必要ならそのコードを載せて明確に質問しないと、
いくら皆さんが博識でも答えられないと思います。

>WAVEの構造体は理解していますが、うまくプログラムを作成できなくて悩んでいます。
ファイル入出力の方が簡単に理解できると思いますが。。。

Joan 2002/08/02(金) 18:37:41
>ファイルの入出力がうまくいきません。よろしければ教えていただけませんか??

ファイルの入力に失敗しているのでしょうか?WAVEファイルへの出力に失敗している
のでしょうか?こっちもわかりません。
前者の場合、失礼ですが質問のレベルが低い割りに課題のレベルが高い感じがします。
後者ならちょっとソースコードを見せてください。どこがうまくいかないのかもどうか
もなにもわかりませんし。

wood 2002/08/03(土) 05:29:45
>wood 2002/07/23(火) 12:21:32
の質問どうなったの?
MSDNサンプルなぜ見ない
見れば、ファイル入出力くらいすぐわかるはず

今までの内容みるとここの返信者に全て仕様固めしてもらって
いるんじゃないですか

だいたい
>スヌーピー 2002/07/30(火) 13:27:27
>よろしければ、細かくサンプルプログラムを頂けたら幸いです。
>まだ完成にはいたって降りません。
これは、どういうことですか
正規購入している方なら「MSDNサンプル」くらい簡単に見つけている
はずだけど

最初の質問原点では
>あるテキストファイルから音声ファイルを作成するプログラム
となっているのに

>スヌーピー 2002/07/31(水) 18:20:40
>RAWというファイルの中身が
となっている
RAWのどこがテキストファイルなのですか?
質問の内容がもともと大雑把過ぎる
このスレッド一度クローズして
わからない部分をソースを交えて細かく質問上げてください

ここの返信者に全てを作ってもらおうと思っているのではないかと
勘違いされても仕方ないのではないですか

スヌーピー 2002/08/13(火) 12:25:39
一応プログラムとしてはできたのですが、エラーが・・・。
error LNK2001が出てしまっております。このエラーはプログラム上でその変数が指定さ
れていないなどのようなことなんでしょうか??
外部シンボル ""int mistaken" (?mistaken@@3HA)" は未解決です
外部シンボル "__imp__mmioAscend@12" は未解決です
外部シンボル "__imp__mmioWrite@12" は未解決です
外部シンボル "__imp__mmioCreateChunk@12" は未解決です
外部シンボル "__imp__mmioSeek@12" は未解決です
外部シンボル "__imp__mmioOpenA@12" は未解決です
外部シンボル ""class CString FilenameS"(?FilenameS@@3VCString@@A)" は未解決です
外部シンボル ""class CString FilenameN" (?FilenameN@@3VCString@@A)" は未解決です
外部シンボル ""unsigned short wBitsPerSample" (?wBitsPerSample@@3GA)" は未解決です
外部シンボル ""unsigned short nChannels" (?nChannels@@3GA)" は未解決です
外部シンボル ""unsigned long nSamplesPerSec" (?nSamplesPerSec@@3KA)" は未解決です
外部シンボル "__imp__mmioClose@8" は未解決です
外部シンボル "__imp__mmioFlush@8" は未解決です

これだけのエラーが出てしまいました。
このエラーをどのようにすればいいのか教えてください。MSDNライブラリーを見て
も・・・

PAI 2002/08/13(火) 13:47:19
...
一応答えておきますが、
(多分)winmm.libをリンクライブラリに追加しましょう。

wood 2002/08/13(火) 20:20:36
PAIさんが言うとおりですが、もう少し説明追加させてください

>外部シンボル "__imp__mmioAscend@12" は未解決です
のうちの”"__imp__”を除いた”@”前までをキーワードに
MSDNを検索すると

”mmioAscend”について検索することができ
その説明には

>対応情報
>  Windows NT/2000:Windows NT 3.1 以降
>  Windows 95/98:Windows 95 以降
>  ヘッダー:mmsystem.h 内で宣言
>  インポートライブラリ:winmm.lib を使用

となっています
もっとMSDN活用してください

PAI 2002/08/13(火) 22:55:47
いや、多分リンクエラーというものがなんなのか理解されてないと思う。

スヌーピー 2002/08/14(水) 10:11:45
MMSYSTEMをつかって、WAVEFORMAT構造体で最初はWAVEFORMATEXを使って作ったのです
が、拡張サイズも含まれて書き込みされてしまうため、PCMWAVEFORMATを使ってプログラ
ムをしています。
typedef struct pcmwaveformat_tag {
    WAVEFORMAT  wf;
    WORD        wBitsPerSample;
} PCMWAVEFORMAT
このようなプログラムがMMSYSTEM.Hには書かれている部分がありますが、WAVEFORMAT処
理させるにはどうしたらいいのでしょうか??WFをどのように書込んだらしたの下記の
処理の値が書込まれるのでしょうか??
typedef struct waveformat_tag {
    WORD    wFormatTag;      /* format type */
    WORD    nChannels;       /* number of channels (i.e. mono, stereo, etc.) */
    DWORD   nSamplesPerSec;  /* sample rate */
    DWORD   nAvgBytesPerSec; /* for buffer estimation */
    WORD    nBlockAlign;     /* block size of data */
} WAVEFORMAT

現状は、RIFF、WAVEサイズ、WAVE、FMT、間で書込んだら00が入り量子化だけ値が書込ま
れてしまいました。

[E-Mail] 2002/08/14(水) 11:18:53
リンクエラーはどうなりました?

Joan 2002/08/14(水) 15:15:11
>WAVEFORMAT構造体で最初はWAVEFORMATEXを使って作ったのです
> が、拡張サイズも含まれて書き込みされてしまうため、
拡張サイズは任意なので、値を0にして書き出してもかまいませんし
面倒であれば、書き出す必要もありません。

拡張サイズを省略するかしないかでこの構造体のサイズが
16 or 18 バイトになるのでそれだけ理解してくれれば問題ないかと。
注意しないと行けないのは、その前に書き出す WAVEFORMATEX の
サイズと同じサイズにするのが重要です。

>WFをどのように書込んだらしたの下記の処理の値が書込まれるのでしょうか??

typedef struct waveformat_tag {
    WORD    wFormatTag;      /* これは PCM_FORMAT です。 */
    WORD    nChannels;       /* 1の場合モノラル、2の場合ステレオです。 */
    DWORD   nSamplesPerSec;  /* サンプリング周波数を入れます */
    DWORD   nAvgBytesPerSec; /*  */
    WORD    nBlockAlign;     /* 量子化"バイト"数です。bit じゃないので注意*/
} WAVEFORMAT

nAvgBytesPerSec は 平均秒間データ転送バイト数です。求め方は
nAvgBytesPerSec = nSamplesPerSec * nChannels * nBlockAlign;
です。

前にもいったように "nChannels", "nSamplesPerSec ", "nBlockAlign"
の3つの値が決まっていないとファイルへの書き出しができません。貴方の
返答がないのでこの辺はいまいち分からないのですが、この3つの変数が
分からない限り WAVE ファイルを作るのは絶対に不可能です。

あと、大変申し訳ない、どうも mmio を使って書き出すと面倒の模様です。
読み込みの時は便利なんですが、書き出した順番に数行程を書き出すだけ
良いので、そのまま書き出した方がシンプルの様です。

一番下の方に書き出しをするサンプルがあります。ただ、VCじゃないので
書き直しが多少必要ですが。
http://www.ne.jp/asahi/nagoya/ahomaro/builder/cpb-061.html

>現状は、RIFF、WAVEサイズ、WAVE、FMT、間で書込んだら00が入り量子化
>だけ値が書込まれてしまいました。
その部分のコードをみせてもらわないとちょっとわかりかねません。

どうでもいいやつ 2002/08/14(水) 15:51:29
>わかりかねません。
わかりかねます・・・・わからない
わかりかねません・・・わかる

日本語って難しい。

スヌーピー 2002/08/14(水) 20:03:57
WAVEの構造体の作成は完成しました。
しかし、波形データを読込んで出力ファイルに書込むことができません。

一応以下に波形データを処理させるプログラムの一部を記載します。


SetFilePointer( m_hMio , 44 , NULL ,FILE_END);
    // 出力ファイルに構造体を書込んだ終端のファイルポインタを0とする
CStdioFile nFile,sFile;
CString data;
nFile.Open( FilenameN , CFile::modeRead | CFile::modeNoTruncate );
nFile.ReadString(data);
    // 入力ファイルからデータを一つ取り出す(一行で一つのデータと考える)
CString dataI = data.Mid(0,6);    // 情報の取得
numI = atoi(dataI);        // CString ⇒ int
dataI = ( numI ) / 256 + 128;
    // 成分を補正する(-32768〜32767)→(0〜255)へ変換
CStdioFile sFile( FilenameS , CFile::modeReadWrite | CFile::modeNoTruncate | 
CFile::typeText);
sFile.WriteString(dataI);

書込むところが悪いようにおもうのですが・・・

??? 2002/08/15(木) 10:47:03
>CString dataI = data.Mid(0,6);    // 情報の取得
>numI = atoi(dataI);        // CString ⇒ int
>dataI = ( numI ) / 256 + 128;

CString型 = int型の計算  これでコンパイル通るの?
char型 = int型の計算 ならたまに使うけど。

>今、あるテキストファイルから音声ファイルを作成するプログラムを作っています。
音声ファイルがなんでCStdioFileなの?

wood 2002/08/15(木) 12:46:03
>書込むところが悪いようにおもうのですが・・・
そのとおり

>音声ファイル
て!
改行コード付のテキストファイルだったんですか?
しりませんでした〜!

>dataI
もバイナリーデータではなく文字列だったんですか
>dataI = ( numI ) / 256 + 128;
この計算式の括弧って特別ないみあるんでしょうな〜
参考のためおしえてくださいよ〜

ま! こんなの答える気にならないし参考にならないと思うんでしょうけど
ここでいっていることは「??? さん」とほぼ一緒ですよ

BAR 2002/08/15(木) 13:35:40
質問の内容がはっきりと書かれていないように思います。
それと、ちゃんと一行ずつデバッグしてますか?

スヌーピー 2002/08/15(木) 19:10:58
CString data = "0x5265ABFF";
CString data1 = data.Mid(0,6);

1行のデータを読込むのに、Joanさんの言われたとおりの方法でデバックをしてみたと
ころ、16進数の値を読込むことができました。
成分を補正する(-32768〜32767)→(0〜255)へ変換処理を行うところで、16進数の値を
読込むことができませんでした。

WAVEフォーマットの情報はMMIOを使って書込むことができました。
しかしながら、0x65654564という情報をまだ書込むことができません。

何かいいアドバイスがあれば教えてください

tiss 2002/08/15(木) 20:42:10
検索するといろいろみつかりました。

http://cgi.members.interq.or.jp/gold/marken/vc/old/msg2725.htm
strtol();

使い方
int    value;
CString  str = "0x0ac4";
char    *end;

value = (int)strtol(str,&end,16);

endがNULLだったら正常で、NULL以外なら認識できなかった文字へのポインタが
入ります。

16は基数です。


そのほか

16進->10進変換
http://www.geocities.jp/dolanpura/vctips/math/hex2int.htm

char(16進)から、int(10進)変換
http://home.att.ne.jp/blue/hira/program01.html#15

wood 2002/08/19(月) 06:02:46
It can not continue yet the question contents   ?

FILE *fopen( const char *filename, const char *mode );
size_t fwrite( const void*buffer, size_t size, size_t count, FILE *stream );


-------------------------------------------------------------
FILE *FP1;
WORD D_WORD;

FP1=fopen( "AAA.WAV”, ”a+b" );
D_WORD=0x65654564;
fwrite( D_WORD, sizeof(D_WORD), 1,FP1);
fclose(FP1);

----------------------------------------------------------------
How is it with such a feeling   
I will reply to the question of everybody neatly

スヌーピー 2002/08/19(月) 13:40:35
一応結果が出力されました。
まだ二つのミスがあります。
一つは、読み込みをCStdioFileで読込んでいるのですが、データがなくなったかを調べ
るにはどのようにしたらいいのでしょうか??

あと、出力で「0x75850001」というデータを読込んで処理した結果が、85 75 01 00とい
うように出力させるにはどうしたらいいのでしょうか??

[E-Mail] 2002/08/19(月) 14:52:49
> 一つは、読み込みをCStdioFileで読込んでいるのですが、データがなくなったかを調べ
> るにはどのようにしたらいいのでしょうか??

CStdioFile::ReadString のヘルプに
「戻り値

  テキスト データを保持するバッファへのポインタを返します。
  データを読み込まずにファイルの終わりに達した場合は NULL 
  または FALSE を返します。」
とありますから、そこで判断すればよいのでは?

wood 2002/08/19(月) 17:28:14
http://www.microsoft.com/japan/developer/library/default.asp

??? 2002/08/19(月) 20:45:42
>あと、出力で「0x75850001」というデータを読込んで処理した結果が、85 75 01 00とい
>うように出力させるにはどうしたらいいのでしょうか??
データを何(型)に読み込んでどういう処理をした後出力するのかによって
適切な方法は違うと思うが?
出力時にCStdioFileを使わないのだけは確か。

2002/08/14(水) 20:03:57のソースでは
(0〜255)に変換したものを書き出したいようだったが??

>一応結果が出力されました。
今何ができていて後何をしたいのかさっぱり???


勝手に課題を出させていただきます。
unsigned char a = 133;
short b = 133;
int c = 133;
float d = 133.0;
double e = 133.0;
上記5つの変数の値をCFile::Write()を用いて
ファイル出力し、その内容をバイナリエディタで確認してください。

wood 2002/08/19(月) 21:10:35
>WaveFile: Sample AVIFile File Handler
と言う「MSDN」サンプル見たことありますか
あなたがここで質問している内容の90%位は解決できるのでは
ないですか

tiss 2002/08/20(火) 07:27:47
>あと、出力で「0x75850001」というデータを読込んで処理した結果が、85 75 01 00と>うように出力させるにはどうしたらいいのでしょうか??

共用体 union を使うと出来そうです♪。 

typedef union {
    int nValue;
    DWORD dw;
    char str[sizeof(int)];
} _uni;
_uni    uni;
uni.str[x] (xは0から3) に対して行った操作は uni.nValue や uni.dw に反映します。

http://black.sakura.ne.jp/~third/c39.html
http://www.kumei.ne.jp/c_lang/intro/no_32.htm

スヌーピー 2002/08/20(火) 11:10:07
皆様ありがとう御座いました。一応完成いたしました。
しかし、リトルエンディアンで出力させたいのですがこの方法ではうまくできませんで
した。このクラスで出力させることはできるのですか??

下記はプログラムの一部文です。
CString data;                            
char *end;
int I,Q;
CStdioFile nFile( FilenameN , CFile::modeRead | CFile::modeNoTruncate | 
CFile::typeText);
switch (wBitsPerSample)    // 量子化ビット数の判定
{
case 8:            // 量子化ビット数が8ビットである
switch (nChannels)    // チャンネル数の判定
{
case 1:            // チャンネル数が1(モノラル)である
{
signed int numI;
CStdioFile sFile( FilenameS , CFile::modeReadWrite | CFile::modeNoTruncate | 
CFile::typeBinary);
//出力ファイルの終端を開始点に設定(WAVEフォーマット情報の後に移動させる)
sFile.Seek( 0 , CFile::end );
// 入力ファイルからデータを一つ取り出す(一行で一つのデータと考える)
while (nFile.ReadString(data) !=NULL)
{
CString dataI = data.Mid(0,6);    // T成分の情報の取得
I = strtol(dataI , &end , 16);    // CStringで読込んだ文字列をlong 整数値に
変換
// I成分を書込むためにI成分を補正する(まず256レベル落とす。範囲が0〜256な
のでそれに128をプラスする)
numI = ( I ) / (256) + (128);
dataI = (numI);
sFile.WriteString((dataI));
}
nFile.Close();
sFile.Close();
}

ayu 2002/08/20(火) 11:42:03
>リトルエンディアンで出力させたいのですがこの方法ではうまくできませんでした。
>このクラスで出力させることはできるのですか??

>リトルエンディアンで出力させたいのですがこの方法ではうまくできませんでした。
うまくいかなかったんですよね?
てことは

>このクラスで出力させることはできるのですか??
できないんじゃないでしょうか?
出力されたファイルをバイナリエディタで見てみてはどうでしょうか?

#解決策としてはbyteスワップがありますが、
#スマートな方法ではありませんね(^^;;

??? 2002/08/20(火) 12:16:54
>このクラスで出力させることはできるのですか??
このクラスって何ですか? CString?

>numI = ( I ) / (256) + (128);
>dataI = (numI);
>sFile.WriteString((dataI));
本当に動くのかなぁ?
後でやってみよ
動くとしても個人的には許しがたいコードだけど。

もしかしてCString以外ファイルに読み書きできないとか思ってない?

? numI = ( I ) / (256) + (128); もしかしてこれって
「成分を補正する(-32768〜32767)→(0〜255)へ変換処理」ではなく
リトルエディアンにするためにビット演算とかしたかったの?

Joan 2002/08/20(火) 20:58:03
>リトルエンディアンで出力させたいのですがこの方法ではうまくできませんでした。

なぜ、エンディアン??もうちょっと、考えてみてください。

>CStdioFile sFile( FilenameS , 
> CFile::modeReadWrite | CFile::modeNoTruncate | CFile::typeBinary);

"CStdioFile"のクラス概要をよく読んでください。これは、『テキストモード』の
ファイル入出力クラスです。派生元の"CFile"クラスを使ってください。
そうすれば、リトルエンディアンのまま書き出せます。

wood 2002/08/20(火) 21:08:28
この人全然、概要呼んでいないみたいですけど
>wood 2002/08/15(木) 12:46:03
の発言、多少皮肉ってますけど完全無視で参考にもされていないみたいだし

"CStdioFile"のクラスで書き込みを行うと文字ストリングの最後のNULLは
改行コードに変換されることくらい知っているはずですけど

??? 2002/08/20(火) 21:45:54
>"CStdioFile"のクラスで書き込みを行うと文字ストリングの最後のNULLは
>改行コードに変換されることくらい知っているはずですけど
知らないんじゃないの?
「リトルエンディアン」って言葉を知っているのが不思議。

とりあえず、
>numI = ( I ) / (256) + (128);
>dataI = (numI);
>sFile.WriteString((dataI));
これは動いた。落ちなかった。感動!!
もちろん書き込まれたデータは役に立たないけど。
でもこんな処理・・・普通考え付くのかなぁ?
計算にもなんの意味もないし。

中途半端なアドバスは無視されるようなので報告だけ。

PAI 2002/08/20(火) 21:53:12
っつーかやりたいことは
テキストの16進数読んで加工してバイナリに落とす。
ってだけの作業でしょ。

誰か金で雇ってやってもらったら?



理解はしてもらえないだろうけど、
私はバイナリファイルを作る場合は、それほど大きなデータでなければ
vector<BYTE>に全部入れてしまってWriteFileで一気に書き出すのが好きです。

好みの問題ですが。

PAI 2002/08/20(火) 21:59:15
CString::operator=(TCHAR)と解釈されるみたいですね。
面白い。

tiss 2002/08/23(金) 06:16:24
dataI = (numI);
sFile.WriteString((dataI));
の部分を
sFile.Write(&numI, sizeof (int));
に変更しないと...

あるいわ
short numS;
sumS = numI;
sFile.Write(&numS, sizeof (short));
とか

CStdioFile
http://homepage2.nifty.com/xad/C/Group16/CStdioFile.htm

File操作
http://www2c.airnet.ne.jp/phy/c++/41.html

古いスレッドには追加発言できません。